ECMA-262 草案 / 2025年5月19日
ECMAScript® 2026 语言规范
介绍
本 Ecma 标准定义了 ECMAScript 2026 语言。这是 ECMAScript 语言规范的第十七版。自 1997 年第一版发布以来,ECMAScript
已经发展成为世界上最广泛使用的通用编程语言之一。它最为人所知的是作为嵌入在 Web 浏览器中的语言,但也被广泛应用于服务器和嵌入式应用程序。
ECMAScript 基于几种原创技术,最著名的是 JavaScript(Netscape)和 JScript(Microsoft)。该语言由 Brendan Eich 在 Netscape
发明,首次出现在该公司的 Navigator 2.0 浏览器中。它出现在 Netscape 的所有后续浏览器中,以及从 Internet Explorer 3.0 开始的所有 Microsoft 浏览器中。
ECMAScript 语言规范的开发始于 1996 年 11 月。本 Ecma 标准的第一版于 1997 年 6 月由 Ecma 大会通过。
该 Ecma 标准已提交给 ISO/IEC JTC 1,按照快速通道程序通过,并于 1998 年 4 月批准为国际标准 ISO/IEC 16262。1998 年 6 月的 Ecma 大会批准了 ECMA-262
的第二版,以保持与 ISO/IEC 16262 完全一致。第一版和第二版之间的变化在性质上是编辑性的。
该标准的第三版引入了强大的正则表达式、更好的字符串处理、新的控制语句、try/catch 异常处理、更严格的错误定义、数值输出格式化以及为预期的未来语言增长而进行的小幅更改。ECMAScript 标准的第三版于
1999 年 12 月由 Ecma 大会通过,并于 2002 年 6 月作为 ISO/IEC 16262:2002 发布。
第三版发布后,ECMAScript 与万维网结合实现了大规模应用,成为几乎所有 Web 浏览器支持的编程语言。为开发 ECMAScript 第四版做了大量工作。然而,这项工作没有完成,也没有作为
ECMAScript 第四版发布,但其中一些内容被纳入了第六版的开发中。
ECMAScript 第五版(作为 ECMA-262 第 5 版发布)编纂了在浏览器实现中已经常见的语言规范的事实解释,并增加了对自第三版发布以来出现的新功能的支持。这些功能包括访问器属性 、对象的反射创建和检查、属性特性的程序控制、额外的数组操作函数、对 JSON
对象编码格式的支持,以及提供增强错误检查和程序安全性的严格模式。第五版于 2009 年 12 月由 Ecma 大会通过。
第五版已提交给 ISO/IEC JTC 1,按照快速通道程序通过,并批准为国际标准 ISO/IEC 16262:2011。ECMAScript 标准的 5.1 版纳入了小幅更正,与 ISO/IEC
16262:2011 文本相同。5.1 版于 2011 年 6 月由 Ecma 大会通过。
第六版的重点开发始于 2009 年,当时第五版正在准备发布。然而,这之前进行了大量的实验和语言增强设计工作,可以追溯到 1999
年第三版的发布。从很真实的意义上说,第六版的完成是十五年努力的顶峰。这一版的目标包括为大型应用程序、库创建以及将 ECMAScript
用作其他语言的编译目标提供更好的支持。它的一些主要增强功能包括模块、类声明、词法块作用域、迭代器 和生成器、用于异步编程的 promise、解构模式和适当的尾调用。ECMAScript
内置库得到扩展,支持额外的数据抽象,包括映射、集合和二进制数值数组,以及对字符串和正则表达式中 Unicode
补充字符的额外支持。内置功能也通过子类化变得可扩展。第六版为常规的、增量的语言和库增强提供了基础。第六版于 2015 年 6 月由大会通过。
ECMAScript 2016 是在 Ecma TC39 新的年度发布节奏和开放开发过程下发布的第一个 ECMAScript 版本。从 ECMAScript 2015 源文档构建了一个纯文本源文档,作为完全在
GitHub 上进一步开发的基础。在这个标准开发的一年中,提交了数百个拉取请求和问题,代表了数千个错误修复、编辑修复和其他改进。此外,还开发了许多软件工具来帮助这一工作,包括
Ecmarkup、Ecmarkdown 和 Grammarkdown。ES2016 还包括对新指数运算符的支持,并向 Array.prototype 添加了一个名为
includes 的新方法。
ECMAScript 2017 引入了异步函数、共享内存和原子操作,以及较小的语言和库增强、错误修复和编辑更新。异步函数通过为返回 promise
的函数提供语法来改善异步编程体验。共享内存和原子操作引入了新的内存模型 ,允许多代理 程序使用原子操作进行通信,确保即使在并行 CPU 上也有明确定义的执行顺序。它还包括 Object
上的新静态方法:Object.values、Object.entries 和
Object.getOwnPropertyDescriptors。
ECMAScript 2018 通过异步迭代器 协议和异步生成器引入了对异步迭代的支持。它还包括四个新的正则表达式功能:dotAll
标志、命名捕获组、Unicode 属性转义和后行断言。最后,它包括对象 rest 和展开属性。
ECMAScript 2019 引入了一些新的内置函数:Array.prototype 上用于扁平化数组的 flat 和
flatMap,用于直接将 Object.entries 的返回值转换为新 Object 的
Object.fromEntries,以及 String.prototype 上的 trimStart 和
trimEnd,作为广泛实现但非标准的 String.prototype.trimLeft 和 trimRight
内置功能的更好命名替代品。此外,它还包括语法和语义的一些小更新。更新的语法包括可选的 catch 绑定参数,以及允许在字符串字面量中使用 U+2028(行分隔符)和 U+2029(段落分隔符)以与 JSON
保持一致。其他更新包括要求 Array.prototype.sort 为稳定排序,要求 JSON.stringify 无论输入如何都返回格式良好的
UTF-8,以及通过要求它返回相应的原始源文本或标准占位符来澄清 Function.prototype.toString。
ECMAScript 2020,第 11 版,为字符串引入了 matchAll 方法,为全局正则表达式生成的所有匹配对象产生一个迭代器 ;import(),一种使用动态说明符异步导入模块的语法;BigInt,用于处理任意精度整数 的新数字原始类型;Promise.allSettled,一个不会短路的新 Promise
组合器;globalThis,访问全局 this 值的通用方式;专用的 export * as ns from 'module'
语法,用于在模块内使用;增加了 for-in 枚举顺序的标准化;import.meta,一个在模块中可用的宿主 填充对象,可能包含关于模块的上下文信息;以及添加了两个新的语法功能来改善处理"nullish"值(undefined
或 null )的工作:空值合并,一个值选择运算符;以及可选链,一个属性访问和函数调用运算符,如果要访问/调用的值为 nullish,则会短路。
ECMAScript 2021,第 12 版,为字符串引入了 replaceAll 方法;Promise.any,一个在输入值被满足时短路的 Promise
组合器;AggregateError,一个同时表示多个错误的新 Error
类型;逻辑赋值运算符(??=、&&=、||=);WeakRef,用于引用目标对象而不阻止其被垃圾回收,以及
FinalizationRegistry,用于管理目标对象被垃圾回收时执行的清理操作的注册和注销;数字字面量的分隔符(1_000);以及
Array.prototype.sort 变得更加精确,减少了导致实现定义 的排序顺序 的情况。
ECMAScript 2022,第 13 版,引入了顶级 await,允许在模块顶级使用该关键字 ;新的类元素:公共和私有实例字段、公共和私有静态字段、私有实例方法和访问器,以及私有静态方法和访问器;类内的静态块,用于执行每个类的评估初始化;#x in obj
语法,用于测试对象上私有字段的存在;通过 /d 标志的正则表达式匹配索引,提供匹配子字符串的开始和结束索引;Error 对象上的
cause 属性,可用于在错误中记录因果链;字符串、数组和 TypedArray 的 at 方法,允许相对索引;以及
Object.hasOwn,Object.prototype.hasOwnProperty 的便捷替代品。
ECMAScript 2023,第 14 版,在 Array.prototype 和 TypedArray.prototype 上引入了
toSorted、toReversed、with、findLast 和
findLastIndex 方法,以及 Array.prototype 上的 toSpliced 方法;增加了对文件开头
#! 注释的支持,以更好地促进可执行的 ECMAScript 文件;并允许在弱集合中使用大多数 Symbol 作为键。
ECMAScript 2024,第 15 版,增加了调整大小和传输 ArrayBuffer 和 SharedArrayBuffer 的功能;增加了新的 RegExp /v
标志,用于创建具有更高级功能的 RegExp 以处理字符串集合;并引入了用于构造 Promise 的 Promise.withResolvers 便捷方法,用于聚合数据的
Object.groupBy 和 Map.groupBy 方法,用于异步等待共享内存更改的 Atomics.waitAsync
方法,以及用于检查和确保字符串仅包含格式良好的 Unicode 的 String.prototype.isWellFormed 和
String.prototype.toWellFormed 方法。
ECMAScript 2025,第 16 版,添加了一个新的 Iterator 全局对象,带有相关的静态和原型方法,用于处理迭代器 ;向
Set.prototype 添加了用于对 Set 执行常见操作的方法;增加了对导入 JSON 模块的支持以及用于声明导入模块属性的语法;添加了用于转义字符串以在正则表达式中安全使用的
RegExp.escape 方法;添加了用于在正则表达式内内联启用和禁用修饰符标志的语法;添加了用于调用可能返回或可能不返回 Promise
的函数并确保结果始终为 Promise 的 Promise.try 方法;并添加了新的 Float16Array
TypedArray 类型以及相关的
DataView.prototype.getFloat16、DataView.prototype.setFloat16 和
Math.f16round 方法。
代表众多组织的数十名个人在 Ecma TC39 内对本版本和以前版本的开发做出了非常重要的贡献。此外,已经形成了一个充满活力的社区来支持 TC39 的 ECMAScript
工作。这个社区审查了许多草案,提交了数千个错误报告,进行了实现实验,贡献了测试套件,并向全球开发者社区介绍了 ECMAScript。不幸的是,无法识别和承认每个为这一努力做出贡献的个人和组织。
Allen Wirfs-Brock
ECMA-262,项目编辑,第 6 版
Brian Terlson
ECMA-262,项目编辑,第 7 至第 10 版
Jordan Harband
ECMA-262,项目编辑,第 10 至第 12 版
Shu-yu Guo
ECMA-262,项目编辑,第 12 至第 16 版
Michael Ficarra
ECMA-262,项目编辑,第 12 至第 16 版
Kevin Gibbons
ECMA-262,项目编辑,第 12 至第 16 版
1 范围
本标准定义了 ECMAScript 2026 通用编程语言。
2 一致性
ECMAScript 的一致性实现必须提供并支持本规范中描述的所有类型、值、对象、属性、函数以及程序语法和语义。
ECMAScript 的一致性实现必须按照最新版本的 Unicode 标准和 ISO/IEC 10646 来解释源文本输入。
提供应用程序编程接口 (API) 的 ECMAScript 一致性实现,如果该 API 支持需要适应不同人类语言和国家使用的语言和文化约定的程序,则必须实现与本规范兼容的最新版本 ECMA-402
中定义的接口。
ECMAScript 的一致性实现可以提供本规范中描述的类型、值、对象、属性和函数之外的其他类型、值、对象、属性和函数。特别是,ECMAScript
的一致性实现可以为本规范中描述的对象提供本规范中未描述的属性以及这些属性的值。
ECMAScript 的一致性实现可以支持本规范中未描述的程序和正则表达式语法。特别是,ECMAScript 的一致性实现可以支持使用本规范子条款 12.7.2 中注明的任何"未来保留字 "的程序语法。
ECMAScript 的一致性实现不得实现子条款 17.1 中列为禁止扩展的任何扩展。
ECMAScript 的一致性实现不得重新定义任何不是实现定义 、实现近似 或宿主定义 的功能。
ECMAScript 的一致性实现可以选择实现或不实现规范可选 子条款。如果实现了任何规范可选行为,则必须实现包含规范可选条款中的所有行为。规范可选条款在本规范中用彩色框中的"规范可选"字样表示,如下所示。
2.1 示例规范可选条款标题
示例条款内容。
ECMAScript 的一致性实现必须实现遗留 子条款,除非它们也被标记为规范可选。遗留子条款中指定的所有语言功能和行为都具有一个或多个不良特征。然而,它们在现有应用程序中的持续使用阻止了它们从本规范中被移除。这些功能不被视为核心
ECMAScript 语言的一部分。程序员在编写新的 ECMAScript 代码时不应使用或假设这些功能和行为的存在。
2.2 示例遗留条款标题
示例条款内容。
2.3 示例遗留规范可选条款标题
示例条款内容。
3 规范性引用
以下引用文档对于本文档的应用是必不可少的。对于注明日期的引用,只适用所引用的版本。对于未注明日期的引用,适用引用文档的最新版本(包括任何修订)。
IEEE
754-2019 ,IEEE 浮点运算标准 。
Unicode 标准。
https://unicode.org/versions/latest
ISO/IEC 10646,信息技术 — 通用多八位编码字符集 (UCS) 加上修订 1:2005、修订 2:2006、修订 3:2008、修订 4:2008,以及其他修订和勘误,或后续版本。
ECMA-402,ECMAScript 国际化 API 规范 ,特指与本规范版本对应的年度版本。
https://www.ecma-international.org/publications-and-standards/standards/ecma-402/
ECMA-404,JSON 数据交换格式 。
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/
4 概述
本节包含对 ECMAScript 语言的非规范性概述。
ECMAScript 是一种面向对象的编程语言,用于在宿主环境 中执行计算和操作计算对象。这里定义的 ECMAScript
并不打算在计算上自给自足;实际上,本规范中没有外部数据输入或计算结果输出的规定。相反,预期 ECMAScript
程序的计算环境不仅提供本规范中描述的对象和其他设施,还提供某些特定于环境的对象,其描述和行为超出了本规范的范围,除了指出它们可能提供某些可从 ECMAScript
程序访问的属性和某些可调用的函数。
ECMAScript
最初被设计用作脚本语言,但现已广泛用作通用编程语言。脚本语言 是一种编程语言,用于操作、自定义和自动化现有系统的设施。在这样的系统中,有用的功能已经通过用户界面可用,脚本语言是将该功能暴露给程序控制的机制。通过这种方式,现有系统被称为提供对象和设施的宿主环境 ,这完善了脚本语言的功能。脚本语言旨在供专业和非专业程序员使用。
ECMAScript 最初被设计为Web 脚本语言 ,提供在浏览器中活跃网页并作为基于 Web 的客户端-服务器架构的一部分执行服务器计算的机制。ECMAScript
现在用于为各种宿主环境 提供核心脚本功能。因此,核心语言在本文档中独立于任何特定的宿主环境 进行规定。
ECMAScript 的使用已经超越了简单的脚本编写,现在用于许多不同环境和规模中编程任务的全谱。随着 ECMAScript
使用的扩展,它提供的功能和设施也在扩展。ECMAScript 现在是一种功能齐全的通用编程语言。
4.1 Web 脚本
Web 浏览器为客户端计算提供 ECMAScript 宿主环境 ,例如,包括表示窗口、菜单、弹出窗口、对话框、文本区域、锚点、框架、历史记录、cookie
和输入/输出的对象。此外,宿主环境 提供了将脚本代码附加到事件(如焦点变化、页面和图像加载、卸载、错误和中止、选择、表单提交和鼠标操作)的方法。脚本代码出现在
HTML 中,显示的页面是用户界面元素和固定及计算文本和图像的组合。脚本代码对用户交互是响应式的,不需要主程序。
Web 服务器为服务器端计算提供不同的宿主环境 ,包括表示请求、客户端和文件的对象;以及锁定和共享数据的机制。通过同时使用浏览器端和服务器端脚本,可以在客户端和服务器之间分布计算,同时为基于
Web 的应用程序提供自定义用户界面。
每个支持 ECMAScript 的 Web 浏览器和服务器都提供自己的宿主环境 ,完成 ECMAScript 执行环境。
4.2 宿主和实现
为了帮助将 ECMAScript 集成到宿主环境 中,本规范将某些设施(例如,抽象操作 )的定义,无论是全部还是部分,推迟到本规范之外的来源。编辑上,本规范区分了以下几种推迟类型。
实现 是进一步定义附录 D 中列举的设施或那些标记为实现定义 或实现近似 的设施的外部来源。在非正式使用中,实现指的是具体的产物,如特定的
Web 浏览器。
实现定义 设施是将其定义推迟到外部来源而无需进一步限定的设施。本规范不对特定行为提出任何建议,符合规范的实现可以在本规范提出的约束内自由选择任何行为。
实现近似 设施是将其定义推迟到外部来源同时推荐理想行为的设施。虽然符合规范的实现可以在本规范提出的约束内自由选择任何行为,但鼓励它们努力接近理想。某些数学运算,如Math.exp ,是实现近似 的。
宿主 是进一步定义附录 D 中列出的设施但不进一步定义其他实现定义 或实现近似 设施的外部来源。在非正式使用中,宿主 指的是所有实现的集合,如所有 Web
浏览器的集合,它们通过附录 D 以相同方式与本规范接口。宿主 通常是外部规范,如 WHATWG HTML (https://html.spec.whatwg.org/ )。换句话说,宿主定义 的设施通常在外部规范中进一步定义。
宿主钩子 是全部或部分由外部来源定义的抽象操作。所有宿主钩子 必须在附录 D 中列出。宿主钩子 必须至少符合以下要求:
宿主定义 设施是将其定义推迟到外部来源而无需进一步限定并在附录 D 中列出的设施。不是宿主 的实现也可以为宿主定义 设施提供定义。
宿主环境 是对所有宿主定义 设施定义的特定选择。宿主环境 通常包括允许获取输入和提供输出的对象或函数,作为全局对象 的宿主定义 属性。
本规范遵循始终使用最具体术语的编辑约定。例如,如果一个设施是宿主定义 的,它不应该被称为实现定义 的。
宿主 和实现都可以通过语言类型、规范类型、抽象操作 、语法产生式、内置对象和本文定义的内置符号与本规范接口。
4.3 ECMAScript 概述
以下是 ECMAScript 的非正式概述——并非语言的所有部分都被描述。这个概述不是标准本身的一部分。
ECMAScript 是基于对象的:基本语言和宿主 设施由对象提供,ECMAScript 程序是一个通信对象的集群。在 ECMAScript
中,对象 是零个或多个属性 的集合,每个属性都有特性 ,这些特性决定了每个属性如何使用——例如,当属性的 Writable
特性设置为 false 时,执行的 ECMAScript
代码尝试将不同值赋给该属性的任何尝试都会失败。属性是容纳其他对象、原始值 或函数 的容器。原始值是以下内置类型之一的成员:Undefined 、Null 、Boolean 、Number 、BigInt 、String
和 Symbol ;对象是内置类型 Object 的成员;函数是可调用对象。通过属性与对象关联的函数称为方法 。
ECMAScript 定义了一个内置对象 集合,完善了 ECMAScript 实体的定义。这些内置对象包括全局对象 ;对语言的运行时语义 基础的对象,包括
Object、Function、Boolean、Symbol 和各种
Error 对象;表示和操作数值的对象,包括 Math、Number 和
Date;文本处理对象 String 和 RegExp;作为值的索引集合的对象,包括
Array 和九种不同类型的类型化数组,其元素都有特定的数值数据表示;键值集合,包括 Map 和
Set 对象;支持结构化数据的对象,包括 JSON
对象、ArrayBuffer、SharedArrayBuffer
和 DataView;支持控制抽象的对象,包括生成器函数和 Promise 对象;以及反射对象,包括
Proxy 和 Reflect。
ECMAScript 还定义了一组内置操作符 。ECMAScript
操作符包括各种一元运算、乘性运算符、加性运算符、按位移位运算符、关系运算符、相等运算符、二元按位运算符、二元逻辑运算符、赋值运算符和逗号运算符。
大型 ECMAScript 程序由模块 支持,模块允许程序被分为多个语句和声明序列。每个模块明确标识它使用的需要由其他模块提供的声明,以及它的哪些声明可供其他模块使用。
ECMAScript 语法有意类似 Java 语法。ECMAScript
语法被放宽以使其能够作为易于使用的脚本语言。例如,变量不需要声明其类型,类型也不与属性关联,定义的函数不需要在调用之前在文本上出现其声明。
4.3.1 对象
尽管 ECMAScript 包含类定义的语法,但 ECMAScript 对象在根本上不是基于类的,如 C++、Smalltalk 或 Java
中的对象。相反,对象可以通过各种方式创建,包括通过字面量表示法或通过构造函数 ,构造函数创建对象然后执行代码,通过为其属性分配初始值来初始化全部或部分对象。每个构造函数 是具有名为
"prototype" 属性的函数,该属性用于实现基于原型的继承 和共享属性 。对象通过在 new
表达式中使用构造函数 创建;例如,new Date(2009, 11) 创建一个新的
Date 对象。在不使用 new 的情况下调用构造函数 的后果取决于构造函数 。例如,Date()
产生当前日期和时间的字符串表示,而不是对象。
每个由构造函数 创建的对象都有一个对其构造函数 的
"prototype"
属性值的隐式引用(称为对象的原型 )。此外,原型可能有一个对其原型的非null 隐式引用,以此类推;这称为原型链 。当对对象中的属性进行引用时,该引用是对原型链中包含该名称属性的第一个对象中该名称的属性的引用。换句话说,首先检查直接提到的对象是否有这样的属性;如果该对象包含命名属性,那就是引用所指的属性;如果该对象不包含命名属性,则接下来检查该对象的原型;以此类推。
图 1:对象/原型关系
在基于类的面向对象语言中,一般来说,状态由实例承载,方法由类承载,继承只是结构和行为的继承。在 ECMAScript 中,状态和方法由对象承载,而结构、行为和状态都被继承。
所有不直接包含其原型包含的特定属性的对象都共享该属性及其值。图 1 说明了这一点:
CF 是一个构造函数 (也是一个对象)。使用 new
表达式创建了五个对象:cf1 、cf2 、cf3 、cf4
和 cf5 。这些对象中的每一个都包含名为 "q1" 和 "q2"
的属性。虚线表示隐式原型关系;例如,cf3 的原型是 CFp 。构造函数
CF 本身有两个属性,名为 "P1" 和 "P2" ,这些属性对
CFp 、cf1 、cf2 、cf3 、cf4
或 cf5 是不可见的。CFp 中名为 "CFP1" 的属性被
cf1 、cf2 、cf3 、cf4 和
cf5 (但不是 CF )共享,以及在 CFp
的隐式原型链中找到的不名为 "q1" 、"q2" 或 "CFP1"
的任何属性。注意 CF 和 CFp 之间没有隐式原型链接。
与大多数基于类的对象语言不同,可以通过为对象赋值来动态添加属性。也就是说,构造函数 不需要命名或为构造对象的所有或任何属性赋值。在上图中,可以通过为
CFp 中的属性赋新值来为
cf1 、cf2 、cf3 、cf4
和 cf5 添加新的共享属性。
虽然 ECMAScript 对象本质上不是基于类的,但基于构造函数 函数、原型对象和方法的常见模式定义类似类的抽象通常是方便的。ECMAScript
内置对象本身遵循这样的类似类的模式。从 ECMAScript 2015 开始,ECMAScript
语言包括语法类定义,允许程序员简洁地定义符合内置对象使用的相同类似类抽象模式的对象。
4.3.2 ECMAScript 的严格变体
ECMAScript
语言认识到一些语言用户可能希望限制使用语言中可用的某些功能的可能性。他们可能出于安全考虑、避免他们认为容易出错的功能、获得增强的错误检查或其他他们选择的原因而这样做。为了支持这种可能性,ECMAScript
定义了语言的严格变体。语言的严格变体排除了常规 ECMAScript
语言的一些特定语法和语义功能,并修改了一些功能的详细语义。严格变体还指定了必须通过在非严格形式的语言未指定为错误的情况下抛出错误异常来报告的额外错误条件。
ECMAScript 的严格变体通常被称为语言的严格模式 。严格模式的选择和使用以及 ECMAScript 的严格模式语法和语义在个别ECMAScript
源文本 单元级别上明确进行,如 11.2.2
中所述。因为严格模式在语法源文本单元级别上被选择,严格模式只施加在这样的源文本单元内具有局部效果的限制。严格模式不限制或修改必须在多个源文本单元中一致运行的
ECMAScript 语义的任何方面。完整的 ECMAScript 程序可以由严格模式和非严格模式ECMAScript
源文本 单元组成。在这种情况下,严格模式只在实际执行在严格模式源文本单元中定义的代码时应用。
为了符合本规范,ECMAScript 实现必须实现完整的无限制 ECMAScript 语言和本规范定义的 ECMAScript
语言的严格变体。此外,实现必须支持将无限制和严格模式源文本单元组合到单个复合程序中。
4.4 术语和定义
就本文档而言,以下术语和定义适用。
4.4.1 实现近似
实现近似 设施是全部或部分由外部来源定义但在本规范中具有推荐的理想行为的设施
4.4.2 实现定义
实现定义 设施是全部或部分由本规范外部来源定义的设施
4.4.3 宿主定义
与实现定义 相同
注
4.4.4 类型
如条款 6 中定义的数据值集合
4.4.5 原始值
Undefined、Null、Boolean、Number、BigInt、Symbol 或 String 类型之一的成员,如条款 6 中定义
注
4.4.6 对象
Object 类型的成员
注
对象是属性的集合,并且有一个原型对象。原型可能是 null 。
4.4.7 构造函数
创建和初始化对象的函数对象
注
构造函数 的
"prototype" 属性的值是用于实现继承和共享属性的原型对象。
4.4.8 原型
为其他对象提供共享属性的对象
注
当构造函数 创建对象时,该对象隐式引用构造函数 的
"prototype" 属性以解决属性引用。构造函数 的 "prototype"
属性可以通过程序表达式 constructor .prototype
引用,添加到对象原型的属性通过继承被所有共享该原型的对象共享。或者,可以使用 Object.create 内置函数创建具有明确指定原型的新对象。
4.4.9 普通对象
对于所有对象必须支持的基本内部方法具有默认行为的对象
4.4.10 异质对象
对于一个或多个基本内部方法没有默认行为的对象
注
4.4.11 标准对象
语义由本规范定义的对象
4.4.12 内置对象
由 ECMAScript 实现指定和提供的对象
注
标准内置对象在本规范中定义。ECMAScript 实现可以指定和提供本规范中未描述的其他类型的内置对象。
4.4.13 undefined 值
在变量未被赋值时使用的原始值
4.4.14 Undefined 类型
唯一值为 undefined 值的类型
4.4.15 null 值
表示故意缺少任何对象值的原始值
4.4.16 Null 类型
唯一值为 null 值的类型
4.4.17 Boolean 值
Boolean 类型 的成员
注
只有两个 Boolean 值,true 和 false 。
4.4.18 Boolean 类型
由原始值 true 和 false 组成的类型
4.4.19 Boolean 对象
Object
类型 的成员,是标准内置
Boolean 构造函数 的实例
注
Boolean 对象通过在 new 表达式中使用 Boolean 构造函数 创建,提供 Boolean
值作为参数。生成的对象有一个内部槽,其值是 Boolean 值。Boolean 对象可以被强制转换为 Boolean 值。
4.4.20 String 值
原始值,是零个或多个 16 位无符号整数 值的有限 有序序列
注
String 值是String
类型 的成员。序列中的每个整数 值通常表示 UTF-16
文本的单个 16 位单元。但是,ECMAScript 对值没有任何限制或要求,除了它们必须是 16 位无符号整数 。
4.4.21 String 类型
所有可能 String 值的集合
4.4.22 String 对象
Object
类型 的成员,是标准内置
String 构造函数 的实例
注
String 对象通过在 new 表达式中使用 String 构造函数 创建,提供 String
值作为参数。生成的对象有一个内部槽,其值是 String 值。String 对象可以通过调用 String 构造函数 作为函数被强制转换为 String
值(22.1.1.1 )。
4.4.23 Number 值
对应于双精度 64 位二进制格式 IEEE 754-2019 值的原始值
注
Number 值是Number
类型 的成员,是数字的直接表示。
4.4.24 Number 类型
所有可能 Number 值的集合,包括 NaN ("非数字")、+∞ 𝔽 (正无穷大)和
-∞ 𝔽 (负无穷大)
4.4.25 Number 对象
Object
类型 的成员,是标准内置
Number 构造函数 的实例
注
Number 对象通过在 new 表达式中使用 Number 构造函数 创建,提供 Number
值作为参数。生成的对象有一个内部槽,其值是 Number 值。Number 对象可以通过调用 Number 构造函数 作为函数被强制转换为 Number
值(21.1.1.1 )。
4.4.26 Infinity
正无限 Number 值的 Number 值
4.4.27 NaN
IEEE
754-2019 NaN("非数字")值的 Number 值
4.4.28 BigInt 值
对应于任意精度整数 值的原始值
4.4.29 BigInt 类型
所有可能 BigInt 值的集合
4.4.30 BigInt 对象
Object
类型 的成员,是标准内置
BigInt 构造函数 的实例
4.4.31 Symbol 值
表示唯一、非 String 对象属性键 的原始值
4.4.32 Symbol 类型
所有可能 Symbol 值的集合
4.4.33 Symbol 对象
Object
类型 的成员,是标准内置
Symbol 构造函数 的实例
4.4.34 函数
Object
类型 的成员,可以作为子程序调用
注
除了其属性外,函数包含可执行代码和状态,这些决定了调用时的行为。函数的代码可能用 ECMAScript 编写,也可能不是。
4.4.35 内置函数
是函数的内置对象
注
内置函数的例子包括 parseInt 和 Math.exp。宿主 或实现可能提供本规范中未描述的其他内置函数。
4.4.36 内置构造函数
是构造函数 的内置函数
注
内置构造函数 的例子包括
Object 和 Function。宿主 或实现可能提供本规范中未描述的其他内置构造函数 。
4.4.37 属性
对象的一部分,将键(String 值或 Symbol 值)与值关联
注
根据属性的形式,值可以直接表示为数据值(原始值、对象或函数对象 )或间接通过一对访问器函数表示。
4.4.38 方法
作为属性值的函数
注
当函数作为对象的方法调用时,对象作为其 this 值传递给函数。
4.4.39 内置方法
是内置函数的方法
注
标准内置方法在本规范中定义。宿主 或实现可能提供本规范中未描述的其他内置方法。
4.4.40 特性
定义属性某些特征的内部值
4.4.41 自有属性
直接包含在其对象中的属性
4.4.42 继承属性
对象的属性,不是自有属性但是对象原型的属性(自有或继承)
4.5 本规范的组织结构
本规范的其余部分组织如下:
章节 5 定义了整个规范中使用的记号约定。
章节 6 到 10 定义了 ECMAScript
程序运行的执行环境。
章节 11 到 17 定义了实际的 ECMAScript
编程语言,包括其语法编码和所有语言功能的执行语义。
章节 18 到 28 定义了 ECMAScript
标准库。它们包括所有标准对象的定义,这些对象可供 ECMAScript 程序在执行时使用。
章节 29
描述了对 SharedArrayBuffer 支持的内存的访问的内存一致性模型以及 Atomics 对象的方法。
5 记号约定
5.1 语法和词法文法
5.1.1 上下文无关文法
上下文无关文法 由若干产生式 组成。每个产生式的左侧 有一个称为非终结符 的抽象符号,右侧 是零个或多个非终结符和终结符 符号的序列。对于每个文法,终结符都从指定的字母表中选取。
链式产生式 是在其右侧恰好有一个非终结符号以及零个或多个终结符的产生式。
从一个由单一特殊非终结符组成的句子开始,称为目标符号 ,给定的上下文无关文法指定一种语言 ,即,通过反复将序列中的任何非终结符替换为以该非终结符作为左侧的产生式的右侧,可能产生的终结符序列的(可能无限的)集合。
5.1.2 词法和 RegExp 文法
ECMAScript 的词法文法 在 第 12
条 中给出。该文法以符合 11.1 中定义的 SourceCharacter 规则的 Unicode
码点作为其终结符。它定义了一组产生式,从目标符号 InputElementDiv 、InputElementTemplateTail 、InputElementRegExp 、InputElementRegExpOrTemplateTail
或 InputElementHashbangOrRegExp
开始,这些产生式描述了此类码点序列如何转换为输入元素序列。
除空白和注释之外的输入元素构成了 ECMAScript 句法文法的终结符,并被称为 ECMAScript 标记 。这些标记是 ECMAScript 语言的保留字 、标识符、字面量和标点符号。此外,行终止符虽然不被视作标记,但也成为输入元素流的一部分,并指导自动分号插入(12.10 )的过程。简单的空白和单行注释会被丢弃,不会出现在句法文法的输入元素流中。如果
MultiLineComment (即形式为
/*…*/ 的注释,无论其是否跨越多行)不包含行终止符,则同样会被简单丢弃;但如果 MultiLineComment
包含一个或多个行终止符,则它会被替换为单个行终止符,该行终止符成为句法文法输入元素流的一部分。
ECMAScript 的 RegExp 文法 在章节 22.2.1 中给出。此文法的终结符也是由 SourceCharacter 定义的代码点。它定义了一组产生式,从目标符号 Pattern 开始,描述如何将代码点序列转换为正则表达式模式。
词法文法和 RegExp 文法的产生式以两个冒号":: "作为分隔标点符号来区分。词法文法和 RegExp 文法共享一些产生式。
5.1.3 数值字符串文法
数值字符串文法 出现在章节 7.1.4.1 中。它以 SourceCharacter
作为终结符,用于从目标符号 StringNumericLiteral
开始将字符串转换为数值(这与数值字面量的词法文法 相似但不同)。
数值字符串文法的产生式以三个冒号"::: "作为标点符号来区分,从不用于解析源文本。
5.1.4 语法文法
ECMAScript 的语法文法 在章节 13 到 16 中给出。此文法以词法文法定义的
ECMAScript 标记作为终结符(5.1.2 )。它定义了一组产生式,从两个可选的目标符号 Script 和 Module 开始,描述标记序列如何构成语法上正确的 ECMAScript 程序独立组件。
当代码点流要被解析为 ECMAScript Script 或
Module
时,首先通过反复应用词法文法将其转换为输入元素流;然后通过单次应用语法文法解析此输入元素流。如果输入元素流中的标记无法解析为目标非终结符(Script 或 Module )的单个实例且没有剩余标记,则输入流在语法上是错误的。
当解析成功时,它构造一个解析树 ,这是一个根树结构,其中每个节点都是一个解析节点 。每个解析节点是文法中符号的一个实例 ;它表示可以从该符号派生的源文本范围。表示整个源文本的解析树根节点是解析的目标符号 的实例。当解析节点是非终结符的实例时,它也是以该非终结符作为左侧的某个产生式的实例。此外,它有零个或多个子节点 ,对应产生式右侧的每个符号:每个子节点都是对应符号实例的解析节点。
为每次解析器调用实例化新的解析节点,即使是相同源文本的解析也从不重用。当且仅当解析节点表示相同的源文本范围、是相同文法符号的实例且来自相同的解析器调用时,才被认为是同一个解析节点 。
注 1
多次解析相同的字符串将导致不同的解析节点。例如,考虑:
let str = "1 + 1;" ;
eval (str);
eval (str);
每次调用 eval 都将 str 的值转换为 ECMAScript
源文本 并执行独立的解析,创建自己独立的解析节点树。即使每次解析都操作从相同字符串值派生的源文本,这些树也是不同的。
注 2
解析节点是规范产物,实现不需要使用类似的数据结构。
语法文法的产生式以仅一个冒号": "作为标点符号来区分。
章节 13 到 16
中呈现的语法文法并不完整地说明哪些标记序列被接受为正确的 ECMAScript Script 或 Module 。某些额外的标记序列也被接受,即那些如果只在序列的某些位置(如行结束符字符之前)添加分号就会被文法描述的序列。此外,如果行结束符字符出现在某些"尴尬"位置,那么文法描述的某些标记序列不被认为是可接受的。
在某些情况下,为了避免歧义,语法文法使用广义产生式,允许不构成有效 ECMAScript Script 或 Module
的标记序列。例如,这种技术用于对象字面量和对象解构模式。在这种情况下,提供更严格的补充文法 来进一步限制可接受的标记序列。通常,早期错误 规则会声明,在某些上下文中,"P 必须覆盖 一个 N ",其中 P 是解析节点(广义产生式的实例),N
是补充文法中的非终结符。这意味着:
最初由 P 匹配的标记序列使用 N 作为目标符号 重新解析。如果
N 接受文法参数,则设置为最初解析 P 时使用的相同值。
如果标记序列可以解析为 N 的单个实例且没有剩余标记,则:
我们将 N 的该实例(对于给定的 P 是唯一的解析节点)称为"被 P 覆盖 的 N "。
N 及其派生产生式的所有早期错误规则也适用于被 P 覆盖的 N 。
否则(如果解析失败),这是早期语法错误。
5.1.5 文法符号
5.1.5.1 终结符号
在 ECMAScript 文法中,一些终结符号以 固定宽度 字体显示。
这些符号必须在源文本中完全按照所写的方式出现。以这种方式指定的所有终结符号代码点
都应理解为来自基本拉丁块的适当 Unicode 代码点,而不是来自其他 Unicode 范围的任何类似代码点。
终结符号中的代码点不能用 \ UnicodeEscapeSequence 表示。
在终结符号为单个 Unicode 代码点的文法中(即词法、正则表达式和数字字符串文法),
产生式中出现的多个连续固定宽度代码点是相同代码点序列的简写,
写作独立的终结符号。
例如,产生式:
HexIntegerLiteral
::
0x
HexDigits
是以下的简写:
HexIntegerLiteral
::
0
x
HexDigits
相比之下,在语法文法中,连续的固定宽度代码点是单个终结符号。
终结符号有另外两种形式:
5.1.5.2 非终结符号和产生式
非终结符号以 斜体 显示。非终结符的定义(也称为"产生式")
由要定义的非终结符的名称后跟一个或多个冒号引入。(冒号的数量表示产生式属于哪个文法。)
然后在后续行中跟随非终结符的一个或多个可选右侧。例如,语法定义:
WhileStatement
:
while
(
Expression
)
Statement
表示非终结符 WhileStatement 代表
token while,后跟左括号 token,后跟 Expression ,后跟右
括号 token,后跟 Statement 。Expression 和 Statement 的出现本身就是
非终结符。另一个例子,语法定义:
ArgumentList
:
AssignmentExpression
ArgumentList
,
AssignmentExpression
表示 ArgumentList 可以代表
单个 AssignmentExpression ,或者 ArgumentList
后跟逗号,后跟 AssignmentExpression 。这个
ArgumentList 的定义是递归的,
即它是根据自身定义的。结果是 ArgumentList 可以包含任意
正数个参数,用逗号分隔,其中每个参数表达式都是 AssignmentExpression 。这种非终结符的递归定义很常见。
5.1.5.3 可选符号
下标后缀 "opt " 可能出现在终结符或非终结符之后,表示可选符号。
包含可选符号的选择实际上指定了两个右侧,一个省略可选元素,一个包含它。这意味着:
VariableDeclaration
:
BindingIdentifier
Initializer opt
是以下的便利缩写:
VariableDeclaration
:
BindingIdentifier
BindingIdentifier
Initializer
并且:
ForStatement
:
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
是以下的便利缩写:
ForStatement
:
for
(
LexicalDeclaration
;
Expression opt
)
Statement
for
(
LexicalDeclaration
Expression
;
Expression opt
)
Statement
这又是以下的缩写:
ForStatement
:
for
(
LexicalDeclaration
;
)
Statement
for
(
LexicalDeclaration
;
Expression
)
Statement
for
(
LexicalDeclaration
Expression
;
)
Statement
for
(
LexicalDeclaration
Expression
;
Expression
)
Statement
所以,在这个例子中,非终结符 ForStatement 实际上有
四个可选的右侧。
5.1.5.4 文法参数
产生式可以通过下标注释的形式 "[parameters] " 进行参数化,
该注释可以作为产生式定义的非终结符号的后缀出现。"parameters " 可以是单个名称
或用逗号分隔的名称列表。参数化产生式是一组产生式的简写,
定义了参数名称的所有组合,在下划线前面,附加到参数化非终结符号。这意味着:
StatementList [Return]
:
ReturnStatement
ExpressionStatement
是以下的便利缩写:
StatementList
:
ReturnStatement
ExpressionStatement
StatementList_Return
:
ReturnStatement
ExpressionStatement
并且:
StatementList [Return,
In] :
ReturnStatement
ExpressionStatement
是以下的缩写:
StatementList
:
ReturnStatement
ExpressionStatement
StatementList_Return
:
ReturnStatement
ExpressionStatement
StatementList_In
:
ReturnStatement
ExpressionStatement
StatementList_Return_In
:
ReturnStatement
ExpressionStatement
多个参数产生组合数量的产生式,并非所有这些产生式都必须在完整文法中引用。
产生式右侧的非终结符引用也可以参数化。例如:
StatementList
:
ReturnStatement
ExpressionStatement [+In]
等价于说:
StatementList
:
ReturnStatement
ExpressionStatement_In
并且:
StatementList
:
ReturnStatement
ExpressionStatement [~In]
等价于:
StatementList
:
ReturnStatement
ExpressionStatement
非终结符引用可以同时具有参数列表和 "opt " 后缀。例如:
VariableDeclaration
:
BindingIdentifier
Initializer [+In] opt
是以下的缩写:
VariableDeclaration
:
BindingIdentifier
BindingIdentifier
Initializer_In
在右侧非终结符引用中,使用 "? " 作为参数名称的前缀
使该参数值依赖于当前产生式左侧符号引用中该参数名称的出现。例如:
VariableDeclaration [In]
:
BindingIdentifier
Initializer [?In]
是以下的缩写:
VariableDeclaration
:
BindingIdentifier
Initializer
VariableDeclaration_In
:
BindingIdentifier
Initializer_In
如果右侧选择以 "[+parameter]" 为前缀,那么该选择只有在引用产生式的非终结符号时使用了命名参数才可用。
如果右侧选择以 "[~parameter]" 为前缀,那么该选择只有在引用产生式的非终结符号时
没有 使用命名参数才可用。这意味着:
StatementList [Return]
: [+Return]
ReturnStatement
ExpressionStatement
是以下的缩写:
StatementList
:
ExpressionStatement
StatementList_Return
:
ReturnStatement
ExpressionStatement
并且:
StatementList [Return]
: [~Return]
ReturnStatement
ExpressionStatement
是以下的缩写:
StatementList
:
ReturnStatement
ExpressionStatement
StatementList_Return
:
ExpressionStatement
5.1.5.5 one of
当单词 "one of " 跟在文法定义中的冒号后面时,它们表示后续行中的每个终结符号
都是一个可选定义。例如,ECMAScript 的词法文法包含产生式:
NonZeroDigit
:: one of 1
2 3 4 5 6
7 8 9
这只是以下的便利缩写:
NonZeroDigit
::
1
2
3
4
5
6
7
8
9
5.1.5.6 [empty]
如果短语 "[empty]" 作为产生式的右侧出现,它表示产生式的右侧不包含终结符或非终结符。
5.1.5.7 前瞻限制
如果短语 "[lookahead = seq ]" 出现在产生式的右侧,
它表示只有当标记序列 seq 是紧随其后的输入标记序列的前缀时,才能使用该产生式。类似地,"[lookahead ∈
set ]"(其中 set 是标记序列的 有限 非空集合)表示只有当 set
中的某个元素是紧随其后的标记序列的前缀时,才能使用该产生式。为了方便起见,集合也可以写作非终结符,在这种情况下,它代表该非终结符可以展开为的所有标记序列的集合。如果非终结符能够展开为无限多个不同的标记序列,则认为这是编辑错误。
这些条件可以被否定。"[lookahead ≠ seq ]" 表示只有当 seq
不是 紧随其后的输入标记序列的前缀时,才能使用包含的产生式,而 "[lookahead ∉ set ]" 表示只有当 set
中没有 元素是紧随其后的标记序列的前缀时,才能使用该产生式。
作为示例,给定定义:
DecimalDigit
:: one of 0
1 2 3 4 5
6 7 8 9
DecimalDigits
::
DecimalDigit
DecimalDigits
DecimalDigit
定义:
LookaheadExample
::
n
[lookahead ∉ { 1 , 3 , 5 ,
7 , 9 }]
DecimalDigits
DecimalDigit
[lookahead ∉ DecimalDigit ]
匹配字母 n 后跟一个或多个十进制数字(其中第一个数字是偶数),或者一个十进制数字后面不跟另一个十进制数字。
注意,当这些短语在语法文法中使用时,可能无法明确地识别紧随其后的标记序列,因为确定后续标记需要知道在后续位置使用哪个词法目标符号 。因此,当这些在语法文法中使用时,如果标记序列
seq 出现在前瞻限制中(包括作为序列集合的一部分),并且词法目标符号 的选择可能改变
seq 是否为结果标记序列的前缀,则认为这是编辑错误。
如果短语 "[no LineTerminator
here]" 出现在语法文法产生式的右侧,它表示该产生式是受限产生式 :如果在输入流的指定位置出现 LineTerminator ,则不能使用该产生式。例如,产生式:
ThrowStatement
:
throw
[no LineTerminator here]
Expression
;
表示如果在脚本的 throw 标记和 Expression 之间出现 LineTerminator ,则不能使用该产生式。
除非受限产生式禁止出现 LineTerminator ,否则在输入元素流中任意两个连续标记之间可以出现任意数量的
LineTerminator ,而不会影响脚本的语法可接受性。
5.1.5.9 but not
产生式的右侧可以通过使用短语 "but not " 然后指出要排除的展开来指定某些展开是不被允许的。例如,产生式:
Identifier
::
IdentifierName
but not ReservedWord
意味着非终结符 Identifier 可以被任何能够替换 IdentifierName
的代码点序列所替换,但前提是相同的代码点序列不能替换 ReservedWord 。
5.1.5.10 描述性短语
最后,少数非终结符通过无衬线字体的描述性短语来描述,这是在列出所有选择不切实际的情况下:
SourceCharacter
::
any Unicode code point
5.2 算法约定
本规范通常使用编号列表来指定算法中的步骤。这些算法用于精确指定 ECMAScript 语言构造所需的语义。这些算法并非旨在暗示使用任何特定的实现技术。实际上,可能存在更有效的算法来实现给定的特性。
算法可以使用有序的、逗号分隔的别名序列进行显式参数化,这些别名可以在算法步骤中用于引用在该位置传入的参数。可选参数用方括号([ , name
])表示,在算法步骤中与必需参数没有区别。剩余参数可以出现在参数列表的末尾,用前导省略号(, ...name )表示。剩余参数将捕获在必需参数和可选参数之后提供的所有参数到一个
列表 中。如果没有此类附加参数,则该 列表 为空。
算法步骤可以细分为顺序的子步骤。子步骤是缩进的,并且它们本身可以进一步划分为缩进的子步骤。使用大纲编号约定来标识子步骤,第一级子步骤用小写字母标记,第二级子步骤用小写罗马数字标记。如果需要三个以上的级别,则这些规则会重复,第四级使用数字标签。例如:
顶层步骤
子步骤。
子步骤。
子子步骤。
子子子步骤
子子子子步骤
子子子子子步骤
一个步骤或子步骤可以写成一个“if”谓词,该谓词对其子步骤进行条件限制。在这种情况下,仅当谓词为真时才应用子步骤。如果一个步骤或子步骤以单词“else”开头,则它是一个谓词,该谓词是同一级别上在前的“if”谓词步骤的否定。
一个步骤可以指定其子步骤的迭代应用。
以“断言 :”开头的步骤断言其算法的不变条件。此类断言用于明确算法中否则将是隐式的不变量。此类断言不增加额外的语义要求,因此实现无需检查。它们仅用于阐明算法。
算法步骤可以使用“令 x 为 someValue ”的形式为任何值声明命名别名。这些别名是引用式的,即 x 和
someValue 都引用相同的基础数据,对其中任何一个的修改对两者都可见。希望避免这种引用式行为的算法步骤应显式复制右侧的值:“令 x 为
someValue 的副本”会创建 someValue 的浅拷贝。
一旦声明,别名就可以在任何后续步骤中引用,并且不得在别名声明之前的步骤中引用。可以使用“将 x 设置为 someOtherValue ”的形式修改别名。
5.2.1 抽象操作
为了便于在规范的多个部分中使用,一些算法(称为抽象操作 )被命名并以参数化函数形式编写,以便可以从其他算法中按名称引用它们。抽象操作通常使用函数应用样式(如
OperationName(arg1 , arg2 ))进行引用。一些抽象操作被视为类规范抽象的多态分派方法。此类方法式抽象操作通常使用方法应用样式(如
someValue .OperationName(arg1 , arg2 ))进行引用。
5.2.2 语法导向操作
语法导向操作 是一种命名操作,其定义由算法组成,每个算法都与 ECMAScript
语法中的一个或多个产生式相关联。具有多个备选定义的产生式通常会为每个备选方案提供一个不同的算法。当算法与语法产生式相关联时,它可以像引用算法参数一样引用产生式备选方案的终结符和非终结符。以这种方式使用时,非终结符指的是解析源文本时匹配的实际备选定义。语法产生式或由其派生的
解析节点 匹配的源文本 是源文本中从参与匹配的第一个终结符的开头开始到参与匹配的最后一个终结符的结尾结束的部分。
当算法与产生式备选方案相关联时,该备选方案通常不带任何“[ ]”语法注释。此类注释仅影响备选方案的语法识别,对备选方案的相关语义没有影响。
语法导向操作通过使用以下算法中的步骤 1 、3 和 4 的约定,使用解析节点以及可选的其他参数来调用:
令 status 为
SomeNonTerminal 的 SyntaxDirectedOperation。
令 someParseNode 为某个源文本的解析结果。
执行 someParseNode 的
SyntaxDirectedOperation。
执行 someParseNode 的
SyntaxDirectedOperation,参数为 "value" 。
除非另有明确规定,否则所有 链式产生式 对于可能应用于该产生式左侧非终结符的每个操作都有一个隐式定义。该隐式定义只是将相同的操作(以及任何参数)重新应用于链式产生式 的唯一右侧非终结符,然后返回结果。例如,假设某个算法有一个步骤的形式为:“返回
块 的 求值 ”,并且有一个产生式:
块 :
{
语句列表
}
但是 求值
操作没有将算法与该产生式关联起来。在这种情况下,求值 操作隐式地包含一个形式如下的关联:
运行时语义:求值
块 :
{
语句列表
}
返回 语句列表 的 求值 。
5.2.3 运行时语义
指定必须在运行时调用的语义的算法称为运行时语义 。运行时语义由 抽象操作 或 语法导向操作 定义。
5.2.3.1 Completion ( completionRecord )
抽象操作 Completion 接受参数 completionRecord (一个 完成记录 )并返回一个 完成记录 。它用于强调正在返回一个
完成记录 。调用时它执行以下步骤:
断言 :completionRecord 是一个 完成记录 。
返回 completionRecord 。
5.2.3.2 抛出异常
算法步骤中说要抛出异常,例如:
抛出一个 TypeError 异常。
与以下含义相同:
返回 ThrowCompletion (一个新创建的
TypeError 对象)。
5.2.3.3 ReturnIfAbrupt
算法步骤中说或等效于:
ReturnIfAbrupt (argument )。
与以下含义相同:
断言 :argument 是一个 完成记录 。
如果 argument 是一个 突然完成 ,则返回
Completion (argument )。
否则,将 argument 设置为 argument .[[Value]] 。
算法步骤中说或等效于:
ReturnIfAbrupt (AbstractOperation())。
与以下含义相同:
令 hygienicTemp 为 AbstractOperation()。
断言 :hygienicTemp 是一个 完成记录 。
如果 hygienicTemp 是一个 突然完成 ,则返回
Completion (hygienicTemp )。
否则,将 hygienicTemp 设置为 hygienicTemp .[[Value]] 。
其中 hygienicTemp 是临时的,并且仅在与 ReturnIfAbrupt 相关的步骤中可见。
算法步骤中说或等效于:
令 result 为 AbstractOperation(ReturnIfAbrupt (argument ))。
与以下含义相同:
断言 :argument 是一个 完成记录 。
如果 argument 是一个 突然完成 ,则返回
Completion (argument )。
否则,将 argument 设置为 argument .[[Value]] 。
令 result 为 AbstractOperation(argument )。
5.2.3.4 ReturnIfAbrupt 简写
以 ? 为前缀的 抽象操作 和 语法导向操作 的调用表示应将
ReturnIfAbrupt 应用于结果 完成记录 。例如,步骤:
? OperationName()。
等效于以下步骤:
ReturnIfAbrupt (OperationName())。
类似地,对于方法应用样式,步骤:
? someValue .OperationName()。
等效于:
ReturnIfAbrupt (someValue .OperationName())。
类似地,前缀 ! 用于指示以下抽象操作或 语法导向操作 的调用永远不会返回
突然完成 ,并且应使用结果
完成记录 的 [[Value]] 字段代替操作的返回值。例如,步骤:
令 val 为 ! OperationName()。
等效于以下步骤:
令 val 为 OperationName()。
断言 :val 是一个 正常完成 。
将 val 设置为 val .[[Value]] 。
语法导向操作 的
运行时语义 通过在操作调用前放置 ! 或
? 来使用此简写:
执行 ! NonTerminal 的 SyntaxDirectedOperation。
5.2.3.5 隐式正常完成
在声明返回 完成记录 的 抽象操作 内的算法中,以及在所有内置函数中,返回值首先传递给
NormalCompletion ,并使用其结果。此规则不适用于
Completion 算法内,或者当返回的值在该步骤中明确标记为 完成记录 时;这些情况是:
如果通过任何其他方式从此类抽象操作返回 完成记录 ,则属于编辑错误。例如,在这些
抽象操作 中,
返回 true 。
与以下任何一种含义相同:
返回 NormalCompletion (true )。
或
令 completion 为 NormalCompletion (true )。
返回 Completion (completion )。
或
返回 完成记录 { [[Type]] : normal , [[Value]] : true , [[Target]] : empty }。
请注意,通过 ReturnIfAbrupt 展开,以下示例是允许的,因为在展开的步骤中,应用
Completion 的结果在突然情况下直接返回,而隐式的 NormalCompletion 应用在正常情况下解包后发生。
返回 ? completion 。
以下示例将是编辑错误,因为正在返回一个 完成记录 ,而没有在该步骤中进行注释。
令 completion 为 NormalCompletion (true )。
返回 completion 。
5.2.4 静态语义
上下文无关文法不足以表达所有规则,这些规则定义输入元素流是否形成一个有效的、可以求值的 ECMAScript 脚本 或 模块 。在某些情况下,需要额外的规则,这些规则可以使用 ECMAScript
算法约定或散文要求来表达。此类规则始终与语法的产生式相关联,并称为产生式的静态语义 。
静态语义规则具有名称,并且通常使用算法定义。命名的静态语义规则与语法产生式相关联,具有多个备选定义的产生式通常会为每个备选方案的每个适用的命名静态语义规则提供一个不同的算法。
一种特殊的静态语义规则是早期错误规则 。早期错误 规则定义了与特定语法产生式相关的早期错误 条件(参见第
17
条)。本规范的算法中并未显式调用大多数早期错误 规则的求值 。一致性实现必须在首次求值 脚本 或 模块 之前,验证用于解析该 脚本 或 模块 的产生式的所有早期错误 规则。如果违反了任何早期错误 规则,则该 脚本 或 模块 无效且无法求值 。
5.2.5 数学运算
本规范引用以下类型的数值:
在本规范的语言中,使用下标后缀来区分不同数值种类的数值。下标 𝔽 指的是数字,下标 ℤ 指的是
BigInts。没有下标后缀的数值指的是数学值 。本规范以十进制表示大多数数值;它也使用 0x 后跟数字 0-9 或 A-F
的形式的数值作为十六进制值。
通常,当本规范引用一个数值时,例如在短语“y 的长度”或“由四个十六进制数字表示的整数 ...”中,而没有明确指定数值种类时,该短语指的是一个数学值 。引用数字或 BigInt
值的短语会明确注释;例如,“...中代码点数量的数字值 ”或“...的BigInt 值 ”。
当本规范中使用术语 整数 时,它指的是一个数学值 ,该值在整数 集合中,除非另有说明。当本规范中使用术语 整数数字值 时,它指的是一个有限 数字值,其数学值 在整数 集合中。
诸如 +、×、= 和 ≥ 之类的数值运算符指的是由操作数类型决定的那些运算。当应用于数学值 时,这些运算符指的是通常的数学运算。当应用于扩展数学值 时,这些运算符指的是扩展实数上的通常数学运算;不确定形式未定义,在本规范中使用它们应被视为编辑错误。当应用于数字时,这些运算符指的是IEEE
754-2019 中的相关运算。当应用于 BigInts 时,这些运算符指的是应用于 BigInt 的数学值 的通常数学运算。应用于混合类型操作数(例如数字和数学值 )的数值运算符未定义,在本规范中应被视为编辑错误。
数学值 与数字或 BigInts 之间的转换在本文档中始终是显式的。从数学值 或扩展数学值 x
到数字的转换表示为“x 的数字值 ”或 𝔽(x ) ,并在 6.1.6.1 中定义。从整数 x 到 BigInt
的转换表示为“x 的BigInt 值 ”或 ℤ(x ) 。从数字或 BigInt x 到数学值 的转换表示为“x 的数学值 ”,或 ℝ(x ) 。+0 𝔽 和
-0 𝔽 的数学值 是数学值 0。非有限 值的数学值 未定义。x 的扩展数学值 对于有限 值是 x 的数学值 ,对于 +∞ 𝔽 和
-∞ 𝔽 分别是 +∞ 和 -∞;对于 NaN 未定义。
数学函数 abs(x ) 产生 x
的绝对值,如果 x < 0 则为 -x ,否则为 x
本身。
数学函数 min(x1 , x2 , … ,
xN ) 产生 x1 到 xN 中数学上最小的值。数学函数 max(x1 , x2 , ..., xN ) 产生 x1 到 xN
中数学上最大的值。这些数学函数的定义域和值域是扩展数学值 。
符号“x 模
y ”(y 必须是有限 且非零)计算一个与 y 同符号(或为零)的值 k ,使得
abs (k ) < abs (y ) 且 x -
k = q × y 对于某个整数 q 成立。
短语“将 x 限制 在 lower 和 upper
之间”的结果(其中 x 是一个扩展数学值 ,lower 和
upper 是数学值 且 lower ≤ upper )是:如果
x < lower 则为 lower ,如果 x > upper 则为
upper ,否则为 x 。
数学函数 floor(x ) 产生不大于
x 的最大整数 (最接近 +∞)。
注意
数学函数 truncate(x )
通过向零取整来移除 x 的小数部分,如果 x < 0 则产生 -floor (-x ) ,否则产生 floor (x ) 。
数学函数 min 、max 、abs 、floor 和 truncate 未针对数字和 BigInts
定义,任何使用非数学值 参数的这些方法的用法在本规范中都应视为编辑错误。
从下界 a 到上界 b 的区间 是一个可能是无限的、可能是空的、相同数值类型的数值集合。每个界限将被描述为包含的或排除的,但不能两者都是。有四种区间,如下所示:
从 a (包含)到 b (包含)的区间 ,也称为从 a 到 b 的闭区间 ,包括所有相同数值类型的数值 x ,使得
a ≤ x ≤ b ,且不包括其他值。
从 a (包含)到 b (排除)的区间 包括所有相同数值类型的数值 x ,使得 a ≤
x < b ,且不包括其他值。
从 a (排除)到 b (包含)的区间 包括所有相同数值类型的数值 x ,使得 a <
x ≤ b ,且不包括其他值。
从 a (排除)到 b (排除)的区间 包括所有相同数值类型的数值 x ,使得 a <
x < b ,且不包括其他值。
例如,从 1(包含)到 2(排除)的区间 包含所有介于 1 和 2 之间的数学值 ,包括 1 但不包括
2。为了定义区间,-0 𝔽 <
+0 𝔽 ,因此,例如,下界为 +0 𝔽 的闭区间 包括
+0 𝔽 但不包括
-0 𝔽 。NaN 从不包含在区间 中。
5.2.6 值表示法
在本规范中,ECMAScript
语言值 以粗体 显示。示例包括
null 、true 或 "hello" 。这些与 ECMAScript
源文本 (如 Function.prototype.apply 或
let n = 42;)相区别。
5.2.7 同一性
在本规范中,规范值和 ECMAScript
语言值 都会进行相等性比较。在比较相等性时,值分为两类。无同一性的值 如果其所有固有特征(例如整数 的大小或序列的长度)都相同,则与其他无同一性的值相等。无同一性的值可以通过完全描述其特征来体现,而无需事先引用。相比之下,每个有同一性的值 都是唯一的,因此只等于其自身。有同一性的值类似于无同一性的值,但具有一个额外的、不可猜测的、不可改变的、普遍唯一的特征,称为同一性 。对现有有同一性的值的引用不能简单地通过描述它们来体现,因为同一性本身是不可描述的;相反,对这些值的引用必须从一个地方显式传递到另一个地方。一些有同一性的值是可变的,因此可以就地更改其特征(除了其同一性),从而使该值的所有持有者都观察到新的特征。无同一性的值永远不等于有同一性的值。
从本规范的角度来看,“是”用于比较两个值的相等性,如“如果 bool 是 true ,则
...”,而“包含”用于使用相等性比较在列表中搜索值,如“如果 list 包含一个 记录 r 使得
r .[[Foo]] 是 true ,则
...”。值的规范同一性 决定了这些比较的结果,并且在本规范中是公理性的。
从 ECMAScript 语言的角度来看,语言值使用 SameValue 抽象操作及其传递调用的 抽象操作 进行相等性比较。这些比较抽象操作 的算法确定了
ECMAScript 语言值 的语言同一性 。
对于规范值,无规范同一性的值的示例包括但不限于:数学值 和扩展数学值 ;ECMAScript
源文本 、代理对 、指令序言 等;UTF-16 代码单元;Unicode
码点;枚举 ;抽象操作 ,包括语法导向操作 、宿主钩子 等;以及有序对。有规范同一性的规范值的示例包括但不限于:任何类型的记录 ,包括属性描述符 、私有元素 等;解析节点 ;列表 ;集合 和关系 ;抽象闭包 ;数据块 ;私有名称 ;执行上下文 和执行上下文栈 ;代理标识符 ;以及WaiterList
记录 。
对于所有 ECMAScript 语言值 ,规范同一性与语言同一性一致,但由
Symbol.for 产生的 Symbol 值除外。无规范同一性和无语言同一性的 ECMAScript 语言值 是 undefined 、null 、布尔值 、字符串 、数字 和BigInts 。有规范同一性和语言同一性的
ECMAScript 语言值 是并非由 Symbol.for 产生的
Symbols 和 对象 。由
Symbol.for 产生的 Symbol 值具有规范同一性,但没有语言同一性。
6 ECMAScript 数据类型和值
本规范中的算法操作的值都具有关联的类型。可能的值类型正是本条款中定义的那些类型。类型进一步分为 ECMAScript 语言类型 和规范类型。
6.1 ECMAScript 语言类型
ECMAScript 语言类型 对应于 ECMAScript 程序员使用 ECMAScript
语言直接操作的值。ECMAScript 语言类型包括 Undefined、Null、Boolean、String、Symbol、Number、BigInt 和 Object。 ECMAScript 语言值 是由 ECMAScript 语言类型表征的值。
6.1.1 Undefined 类型
Undefined 类型只有一个值,称为 undefined 。任何未赋值的变量都具有值 undefined 。
6.1.2 Null 类型
Null 类型只有一个值,称为 null 。
6.1.3 Boolean 类型
Boolean 类型 表示一个逻辑实体,具有两个值,称为
true 和 false 。
6.1.4 字符串类型
字符串类型 是所有长度不超过 253 - 1 个元素的零个或多个 16
位无符号整数 值(“元素”)的有序序列的集合。字符串类型通常用于在运行的 ECMAScript
程序中表示文本数据,在这种情况下,字符串中的每个元素都被视为一个 UTF-16 代码单元值。每个元素都被认为在序列中占据一个位置。这些位置用非负整数 进行索引。第一个元素(如果存在)位于索引
0,下一个元素(如果存在)位于索引 1,依此类推。字符串的长度是其中元素的数量(即 16 位值的数量)。空字符串的长度为零,因此不包含任何元素。
不解释字符串内容的 ECMAScript 操作不应用任何进一步的语义。解释字符串值的操作将每个元素视为单个 UTF-16 代码单元。但是,ECMAScript
不限制这些代码单元的值或它们之间的关系,因此将字符串内容进一步解释为以 UTF-16 编码的 Unicode 码点序列的操作必须考虑到格式错误的子序列。此类操作对数值在 闭区间
0xD800 到 0xDBFF(由 Unicode 标准定义为前导代理项 ,或更正式地称为高位代理代码单元 )内的每个代码单元以及数值在 闭区间 0xDC00 到 0xDFFF(定义为后尾代理项 ,或更正式地称为低位代理代码单元 )内的每个代码单元应用以下规则进行特殊处理:
一个既不是前导代理项 也不是后尾代理项 的代码单元被解释为具有相同值的码点。
一个由两个代码单元组成的序列,其中第一个代码单元 c1 是一个前导代理项 ,第二个代码单元 c2
是一个后尾代理项 ,则该序列是一个代理对 ,并被解释为具有值 (c1 - 0xD800) × 0x400 +
(c2 - 0xDC00) + 0x10000 的码点。(参见 11.1.3 )
一个前导代理项 或后尾代理项 ,但不是代理对 的一部分,则被解释为具有相同值的码点。
函数 String.prototype.normalize(参见 22.1.3.15 )可用于显式规范化字符串值。String.prototype.localeCompare(参见
22.1.3.12 )在内部规范化字符串值,但没有其他操作会隐式规范化它们操作的字符串。除非另有说明,否则操作结果对语言和/或区域设置不敏感。
注意
这种设计背后的基本原理是使字符串的实现尽可能简单和高性能。如果 ECMAScript 源文本 采用规范化形式 C,则只要字符串字面量不包含任何
Unicode 转义序列,就可以保证它们也是规范化的。
在本规范中,短语“A 、B 、... 的字符串连接 ”(其中每个参数都是字符串值、代码单元或代码单元序列)表示其代码单元序列是每个参数(按顺序)的代码单元(按顺序)连接而成的字符串值。
短语“S 从 inclusiveStart 到 exclusiveEnd 的子字符串 ”(其中 S 是字符串值或代码单元序列,inclusiveStart 和
exclusiveEnd 是整数 )表示由 S 的从索引 inclusiveStart 开始到索引
exclusiveEnd 之前结束的连续代码单元组成的字符串值(当 inclusiveStart = exclusiveEnd
时为空字符串)。如果省略“to”后缀,则使用 S 的长度作为 exclusiveEnd 的值。
短语“ASCII 词字符 ”表示以下字符串值,该值仅由 Unicode
基本拉丁块中的所有字母和数字以及 U+005F (LOW LINE) 组成:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_" 。
由于历史原因,它对各种算法具有重要意义。
6.1.4.1 StringIndexOf ( string ,
searchValue , fromIndex )
抽象操作 StringIndexOf 接受参数 string (一个字符串)、searchValue (一个字符串) 和
fromIndex (一个非负整数 ),并返回一个非负整数 或
not-found 。调用时它执行以下步骤:
令 len 为 string 的长度。
如果 searchValue 是空字符串且 fromIndex ≤ len ,则返回
fromIndex 。
令 searchLen 为 searchValue 的长度。
对于每个整数
i ,使得 fromIndex ≤ i ≤ len -
searchLen ,按升序执行:
令 candidate 为 string 从 i 到 i +
searchLen 的子字符串 。
如果 candidate 是 searchValue ,则返回 i 。
返回 not-found 。
注1
如果 searchValue 是空字符串且 fromIndex ≤ string 的长度,则此算法返回
fromIndex 。空字符串实际上在字符串中的每个位置都能找到,包括最后一个代码单元之后。
注2
如果 fromIndex + searchValue 的长度 > string 的长度,则此算法始终返回
not-found 。
6.1.4.2 StringLastIndexOf ( string ,
searchValue , fromIndex )
抽象操作 StringLastIndexOf 接受参数 string (一个字符串)、searchValue (一个字符串) 和
fromIndex (一个非负整数 ),并返回一个非负整数 或
not-found 。调用时它执行以下步骤:
令 len 为 string 的长度。
令 searchLen 为 searchValue 的长度。
断言 :fromIndex + searchLen
≤ len 。
对于每个整数
i ,使得 0 ≤ i ≤ fromIndex ,按降序执行:
令 candidate 为 string 从 i 到 i +
searchLen 的子字符串 。
如果 candidate 是 searchValue ,则返回 i 。
返回 not-found 。
注意
如果 searchValue 是空字符串,则此算法返回
fromIndex 。空字符串实际上在字符串中的每个位置都能找到,包括最后一个代码单元之后。
6.1.5 Symbol 类型
Symbol 类型 是所有可用作对象属性键(6.1.7 )的非字符串值的集合。
每个可能的 Symbol 值都是唯一且不可变的。
每个 Symbol 值都不可变地持有一个关联值,称为 [[Description]] ,该值要么是
undefined ,要么是字符串值。
6.1.5.1 知名符号
知名符号是本规范算法明确引用的内置 Symbol 值。它们通常用作属性的键,这些属性的值充当规范算法的扩展点。除非另有规定,否则知名符号值由所有领域 (9.3 )共享。
在本规范中,使用标准的内在符号表示法 引用知名符号,其中内在符号是表
1 中列出的值之一。
注意
本规范的先前版本使用 @@name 形式的表示法,而当前版本将使用
%Symbol.name%。特别是,使用了以下名称:@@asyncIterator、@@hasInstance、@@isConcatSpreadable、@@iterator 、@@match、@@matchAll、@@replace、@@search、@@species、@@split、@@toPrimitive、@@toStringTag
和 @@unscopables。
表 1:知名符号
规范名称
[[Description]]
值和用途
%Symbol.asyncIterator%
"Symbol.asyncIterator"
一个返回对象默认异步迭代器 的方法。由
for-await-of 语句的语义调用。
%Symbol.hasInstance%
"Symbol.hasInstance"
一个确定构造函数 对象是否将一个对象识别为该构造函数 的实例的方法。由
instanceof 运算符的语义调用。
%Symbol.isConcatSpreadable%
"Symbol.isConcatSpreadable"
一个布尔值属性,如果为 true,则表示一个对象应由 Array.prototype.concat
展平为其数组元素。
%Symbol.iterator%
"Symbol.iterator"
一个返回对象默认迭代器 的方法。由 for-of
语句的语义调用。
%Symbol.match%
"Symbol.match"
一个正则表达式方法,用于将正则表达式与字符串进行匹配。由 String.prototype.match
方法调用。
%Symbol.matchAll%
"Symbol.matchAll"
一个正则表达式方法,返回一个迭代器 ,该迭代器产生正则表达式与字符串匹配的结果。由
String.prototype.matchAll
方法调用。
%Symbol.replace%
"Symbol.replace"
一个正则表达式方法,用于替换字符串中匹配的子字符串。由 String.prototype.replace
方法调用。
%Symbol.search%
"Symbol.search"
一个正则表达式方法,返回字符串中与正则表达式匹配的索引。由 String.prototype.search
方法调用。
%Symbol.species%
"Symbol.species"
一个函数值属性,是用于创建派生对象的构造函数 。
%Symbol.split%
"Symbol.split"
一个正则表达式方法,用于在与正则表达式匹配的索引处拆分字符串。由 String.prototype.split
方法调用。
%Symbol.toPrimitive%
"Symbol.toPrimitive"
一个将对象转换为相应原始值的方法。由 ToPrimitive 抽象操作调用。
%Symbol.toStringTag%
"Symbol.toStringTag"
一个字符串值属性,用于创建对象的默认字符串描述。由内置方法 Object.prototype.toString
访问。
%Symbol.unscopables%
"Symbol.unscopables"
一个对象值属性,其自身和继承的属性名称是从关联对象的 with 环境绑定中排除的属性名称。
6.1.6 数字类型
ECMAScript 有两种内置的数字类型:Number 和 BigInt。以下抽象操作 是在这些数字类型上定义的。“结果”列显示返回类型,并指示该操作的某些调用是否可能返回突然完成 。
表 2:数字类型操作
由于数字类型通常无法在不损失精度或截断的情况下进行转换,因此 ECMAScript 语言不提供这些类型之间的隐式转换。在调用需要另一种类型的函数时,程序员必须显式调用
Number 和 BigInt 函数在类型之间进行转换。
注意
ECMAScript 的第一版及后续版本为某些运算符提供了可能损失精度或截断 的隐式数字转换。为了向后兼容,这些遗留的隐式转换得以保留,但为了最大限度地减少程序员出错的机会,并为未来版本中广义值类型 的选择留有余地,BigInt
不提供这些转换。
6.1.6.1 Number 类型
Number 类型 恰好有
18,437,736,874,454,810,627 (即 264 - 253 +
3 ) 个值,表示 IEEE 754-2019 二进制64位双精度浮点值,如 IEEE
二进制浮点算术标准中所指定,但 IEEE 标准中的 9,007,199,254,740,990 (即 253 -
2 ) 个不同的 NaN 值在 ECMAScript 中表示为单个特殊的 NaN
值。(注意,NaN 值由程序表达式 NaN 产生。)在某些实现中,外部代码可能能够检测到各种 NaN
值之间的差异,但这种行为是实现定义的 ;对于 ECMAScript 代码,所有
NaN 值彼此之间无法区分。
注意
在将 Number 值存储到 ArrayBuffer (参见 25.1 ) 或
SharedArrayBuffer (参见 25.2 )
后可能观察到的位模式不一定与 ECMAScript 实现使用的该 Number 值的内部表示相同。
还有另外两个特殊值,称为正无穷大 和负无穷大 。为简洁起见,出于说明目的,这些值也分别用符号
+∞ 𝔽 和 -∞ 𝔽 表示。(注意,这两个无限 Number
值由程序表达式 +Infinity (或简称 Infinity) 和 -Infinity 产生。)
其余 18,437,736,874,454,810,624 (即 264 -
253 ) 个值称为有限 数。其中一半是正数,一半是负数;对于每个有限 正 Number 值,都有一个对应的具有相同大小的负值。
注意,既有正零 也有负零 。为简洁起见,出于说明目的,这些值也分别用符号
+0 𝔽 和 -0 𝔽 表示。(注意,这两个不同的零
Number 值由程序表达式 +0 (或简称 0) 和 -0 产生。)
18,437,736,874,454,810,622 (即 264 - 253 -
2 ) 个有限 非零值有两种:
其中 18,428,729,675,200,069,632 (即 264 -
254 ) 个是规范化的,形式为
s × m × 2e
其中 s 是 1 或 -1,m 是区间 [252 , 253 ) 内的整数 ,e
是闭区间 [-1074, 971] 内的整数 。
其余 9,007,199,254,740,990 (即 253 - 2 )
个值是非规范化的,形式为
s × m × 2e
其中 s 是 1 或 -1,m 是区间 (0, 252 ) 内的整数 ,e 是 -1074。
注意,所有大小不超过 253 的正负整数 都可以在 Number 类型中表示。整数 0 在 Number
类型中有两种表示:+0 𝔽 和 -0 𝔽 。
如果一个有限 数非零,并且用于表示它(以上述两种形式之一)的整数 m
是奇数,则该数具有奇数有效数 。否则,它具有偶数有效数 。
在本规范中,短语“x 的 Number 值 ”(其中 x 表示一个精确的实数数学量,甚至可能是一个无理数,如
π)指的是按以下方式选择的 Number 值。考虑 Number 类型的所有有限 值的集合,去掉 -0 𝔽 ,并向其添加两个
Number 类型中无法表示的附加值,即 21024 (即 +1 × 253 ×
2971 ) 和 -21024 (即
-1 × 253 × 2971 )。选择此集合中与
x 值最接近的成员。如果集合中的两个值同样接近,则选择具有偶数有效数的那个;为此,两个额外的值 21024 和 -21024 被认为具有偶数有效数。最后,如果选择了 21024 ,则将其替换为
+∞ 𝔽 ;如果选择了 -21024 ,则将其替换为
-∞ 𝔽 ;如果选择了 +0 𝔽 ,则当且仅当
x < 0 时将其替换为 -0 𝔽 ;任何其他选择的值保持不变。结果是 x
的Number
值 。(此过程与 IEEE 754-2019 roundTiesToEven 模式的行为完全对应。)
+∞ 的Number
值 是 +∞ 𝔽 ,-∞ 的Number
值 是 -∞ 𝔽 。
某些 ECMAScript 运算符仅处理特定范围内的整数 ,例如闭区间 [-231 , 231 -
1 ] 或闭区间 [0, 216 - 1 ]。这些运算符接受 Number
类型的任何值,但首先将每个此类值转换为预期范围内的整数 值。请参见 7.1 中数字转换操作的说明。
6.1.6.1.1 Number::unaryMinus ( x )
抽象操作 Number::unaryMinus 接受参数 x (一个 Number) 并返回一个 Number。调用时它执行以下步骤:
如果 x 是 NaN ,则返回 NaN 。
返回 x 的负值;即,计算一个具有相同大小但符号相反的 Number。
6.1.6.1.2 Number::bitwiseNOT ( x )
抽象操作 Number::bitwiseNOT 接受参数 x (一个 Number) 并返回一个整数
Number 。调用时它执行以下步骤:
令 oldValue 为 ! ToInt32 (x )。
返回 oldValue 的按位补码。结果的数学值 可以精确地表示为一个
32 位二进制补码位串。
6.1.6.1.3 Number::exponentiate ( base ,
exponent )
抽象操作 Number::exponentiate 接受参数 base (一个 Number) 和 exponent (一个
Number) 并返回一个 Number。它返回一个实现近似 的值,表示
base 的 exponent 次幂的结果。调用时它执行以下步骤:
如果 exponent 是 NaN ,则返回 NaN 。
如果 exponent 是 +0 𝔽 或
-0 𝔽 ,则返回 1 𝔽 。
如果 base 是 NaN ,则返回 NaN 。
如果 base 是 +∞ 𝔽 ,则
如果 exponent > +0 𝔽 ,则返回
+∞ 𝔽 。否则,返回
+0 𝔽 。
如果 base 是 -∞ 𝔽 ,则
如果 exponent > +0 𝔽 ,则
如果 exponent 是一个奇数整数
Number ,则返回
-∞ 𝔽 。否则,返回
+∞ 𝔽 。
否则,
如果 exponent 是一个奇数整数
Number ,则返回
-0 𝔽 。否则,返回
+0 𝔽 。
如果 base 是 +0 𝔽 ,则
如果 exponent > +0 𝔽 ,则返回
+0 𝔽 。否则,返回
+∞ 𝔽 。
如果 base 是 -0 𝔽 ,则
如果 exponent > +0 𝔽 ,则
如果 exponent 是一个奇数整数
Number ,则返回
-0 𝔽 。否则,返回
+0 𝔽 。
否则,
如果 exponent 是一个奇数整数
Number ,则返回
-∞ 𝔽 。否则,返回
+∞ 𝔽 。
断言 :base 是有限的 ,并且既不是
+0 𝔽 也不是 -0 𝔽 。
如果 exponent 是 +∞ 𝔽 ,则
如果 abs (ℝ (base )) >
1,则返回 +∞ 𝔽 。
如果 abs (ℝ (base )) =
1,则返回 NaN 。
如果 abs (ℝ (base )) <
1,则返回 +0 𝔽 。
如果 exponent 是 -∞ 𝔽 ,则
如果 abs (ℝ (base )) >
1,则返回 +0 𝔽 。
如果 abs (ℝ (base )) =
1,则返回 NaN 。
如果 abs (ℝ (base )) <
1,则返回 +∞ 𝔽 。
断言 :exponent 是有限的 ,并且既不是
+0 𝔽 也不是 -0 𝔽 。
如果 base < -0 𝔽 且 exponent
不是一个整数 Number ,则返回
NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (base )
的 ℝ (exponent ) 次幂的结果。
注意
当 base 是 1 𝔽 或
-1 𝔽 且 exponent 是
+∞ 𝔽 或 -∞ 𝔽 时,或者当
base 是 1 𝔽 且 exponent 是
NaN 时,base ** exponent
的结果与 IEEE 754-2019 不同。ECMAScript
的第一版为此操作指定了 NaN 的结果,而 IEEE 754 的后续修订版指定了
1 𝔽 。出于兼容性原因,保留了历史上的 ECMAScript 行为。
6.1.6.1.4 Number::multiply ( x , y )
抽象操作 Number::multiply 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Number。它根据 IEEE 754-2019 二进制双精度算术规则执行乘法,产生
x 和 y 的乘积。调用时它执行以下步骤:
如果 x 是 NaN 或 y 是
NaN ,则返回 NaN 。
如果 x 是 +∞ 𝔽 或
-∞ 𝔽 ,则
如果 y 是 +0 𝔽 或
-0 𝔽 ,则返回 NaN 。
如果 y > +0 𝔽 ,则返回
x 。
返回 -x 。
如果 y 是 +∞ 𝔽 或
-∞ 𝔽 ,则
如果 x 是 +0 𝔽 或
-0 𝔽 ,则返回 NaN 。
如果 x > +0 𝔽 ,则返回
y 。
返回 -y 。
如果 x 是 -0 𝔽 ,则
如果 y 是 -0 𝔽 或 y <
-0 𝔽 ,则返回
+0 𝔽 。
否则,返回 -0 𝔽 。
如果 y 是 -0 𝔽 ,则
如果 x < -0 𝔽 ,则返回
+0 𝔽 。
否则,返回 -0 𝔽 。
返回 𝔽 (ℝ (x ) ×
ℝ (y ))。
注意
6.1.6.1.5 Number::divide ( x , y )
抽象操作 Number::divide 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Number。它根据 IEEE 754-2019 二进制双精度算术规则执行除法,产生
x 和 y 的商,其中 x 是被除数,y 是除数。调用时它执行以下步骤:
如果 x 是 NaN 或 y 是
NaN ,则返回 NaN 。
如果 x 是 +∞ 𝔽 或
-∞ 𝔽 ,则
如果 y 是 +∞ 𝔽 或
-∞ 𝔽 ,则返回 NaN 。
如果 y 是 +0 𝔽 或 y >
+0 𝔽 ,则返回 x 。
返回 -x 。
如果 y 是 +∞ 𝔽 ,则
如果 x 是 +0 𝔽 或 x >
+0 𝔽 ,则返回
+0 𝔽 。否则,返回
-0 𝔽 。
如果 y 是 -∞ 𝔽 ,则
如果 x 是 +0 𝔽 或 x >
+0 𝔽 ,则返回
-0 𝔽 。否则,返回
+0 𝔽 。
如果 x 是 +0 𝔽 或
-0 𝔽 ,则
如果 y 是 +0 𝔽 或
-0 𝔽 ,则返回 NaN 。
如果 y > +0 𝔽 ,则返回
x 。
返回 -x 。
如果 y 是 +0 𝔽 ,则
如果 x > +0 𝔽 ,则返回
+∞ 𝔽 。否则,返回
-∞ 𝔽 。
如果 y 是 -0 𝔽 ,则
如果 x > +0 𝔽 ,则返回
-∞ 𝔽 。否则,返回
+∞ 𝔽 。
返回 𝔽 (ℝ (x ) /
ℝ (y ))。
6.1.6.1.6 Number::remainder ( n , d )
抽象操作 Number::remainder 接受参数 n (一个 Number) 和 d (一个 Number) 并返回一个
Number。它产生其操作数隐式除法的余数,其中 n 是被除数,d 是除数。调用时它执行以下步骤:
如果 n 是 NaN 或 d 是
NaN ,则返回 NaN 。
如果 n 是 +∞ 𝔽 或
-∞ 𝔽 ,则返回 NaN 。
如果 d 是 +∞ 𝔽 或
-∞ 𝔽 ,则返回 n 。
如果 d 是 +0 𝔽 或
-0 𝔽 ,则返回 NaN 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,则返回 n 。
断言 :n 和 d 是有限的 且非零。
令 quotient 为 ℝ (n ) / ℝ (d )。
令 q 为 truncate (quotient )。
令 r 为 ℝ (n ) - (ℝ (d ) × q )。
如果 r = 0 且 n < -0 𝔽 ,则返回
-0 𝔽 。
返回 𝔽 (r )。
注1
在 C 和 C++ 中,余数运算符仅接受整数操作数;在 ECMAScript 中,它也接受浮点操作数。
注2
由
% 运算符计算的浮点余数运算的结果与
IEEE
754-2019 定义的“余数”运算不同。
IEEE 754-2019
“余数”运算计算的是舍入除法的余数,而不是截断除法的余数,因此其行为与通常的
整数 余数运算符不同。相反,ECMAScript
语言定义
% 在浮点运算上的行为类似于 Java
整数 余数运算符的行为;这可以与 C
库函数 fmod 进行比较。
6.1.6.1.7 Number::add ( x , y )
抽象操作 Number::add 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Number。它根据 IEEE 754-2019
二进制双精度算术规则执行加法,产生其参数的和。调用时它执行以下步骤:
如果 x 是 NaN 或 y 是
NaN ,则返回 NaN 。
如果 x 是 +∞ 𝔽 且 y 是
-∞ 𝔽 ,则返回 NaN 。
如果 x 是 -∞ 𝔽 且 y 是
+∞ 𝔽 ,则返回 NaN 。
如果 x 是 +∞ 𝔽 或
-∞ 𝔽 ,则返回 x 。
如果 y 是 +∞ 𝔽 或
-∞ 𝔽 ,则返回 y 。
断言 :x 和 y 都是有限的 。
如果 x 是 -0 𝔽 且 y 是
-0 𝔽 ,则返回 -0 𝔽 。
返回 𝔽 (ℝ (x ) +
ℝ (y ))。
注意
6.1.6.1.8 Number::subtract ( x , y )
抽象操作 Number::subtract 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Number。它执行减法,产生其操作数的差;x 是被减数,y 是减数。调用时它执行以下步骤:
返回 Number::add (x ,
Number::unaryMinus (y ))。
注意
x - y 总是产生与 x + (-y) 相同的结果。
6.1.6.1.9 Number::leftShift ( x , y )
抽象操作 Number::leftShift 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个整数
Number 。调用时它执行以下步骤:
令 lNum 为 ! ToInt32 (x )。
令 rNum 为 ! ToUint32 (y )。
令 shiftCount 为 ℝ (rNum ) modulo 32。
返回将 lNum 左移 shiftCount 位的结果。结果的数学值 可以精确地表示为一个 32 位二进制补码位串。
6.1.6.1.10 Number::signedRightShift ( x ,
y )
抽象操作 Number::signedRightShift 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个整数
Number 。调用时它执行以下步骤:
令 lNum 为 ! ToInt32 (x )。
令 rNum 为 ! ToUint32 (y )。
令 shiftCount 为 ℝ (rNum ) modulo 32。
返回对 lNum 执行符号扩展右移 shiftCount 位的结果。最高有效位被传播。结果的数学值 可以精确地表示为一个 32 位二进制补码位串。
6.1.6.1.11 Number::unsignedRightShift ( x ,
y )
抽象操作 Number::unsignedRightShift 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个整数
Number 。调用时它执行以下步骤:
令 lNum 为 ! ToUint32 (x )。
令 rNum 为 ! ToUint32 (y )。
令 shiftCount 为 ℝ (rNum ) modulo 32。
返回对 lNum 执行零填充右移 shiftCount 位的结果。空出的位用零填充。结果的数学值 可以精确地表示为一个 32 位无符号位串。
6.1.6.1.12 Number::lessThan ( x , y )
抽象操作 Number::lessThan 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Boolean 或 undefined 。调用时它执行以下步骤:
如果 x 是 NaN ,则返回 undefined 。
如果 y 是 NaN ,则返回 undefined 。
如果 x 是 y ,则返回 false 。
如果 x 是 +0 𝔽 且 y 是
-0 𝔽 ,则返回 false 。
如果 x 是 -0 𝔽 且 y 是
+0 𝔽 ,则返回 false 。
如果 x 是 +∞ 𝔽 ,则返回
false 。
如果 y 是 +∞ 𝔽 ,则返回
true 。
如果 y 是 -∞ 𝔽 ,则返回
false 。
如果 x 是 -∞ 𝔽 ,则返回
true 。
断言 :x 和 y 是有限的 。
如果 ℝ (x )
< ℝ (y ),则返回
true 。否则,返回 false 。
6.1.6.1.13 Number::equal ( x , y )
抽象操作 Number::equal 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Boolean。调用时它执行以下步骤:
如果 x 是 NaN ,则返回 false 。
如果 y 是 NaN ,则返回 false 。
如果 x 是 y ,则返回 true 。
如果 x 是 +0 𝔽 且 y 是
-0 𝔽 ,则返回 true 。
如果 x 是 -0 𝔽 且 y 是
+0 𝔽 ,则返回 true 。
返回 false 。
6.1.6.1.14 Number::sameValue ( x , y )
抽象操作 Number::sameValue 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Boolean。调用时它执行以下步骤:
如果 x 是 NaN 且 y 是
NaN ,则返回 true 。
如果 x 是 +0 𝔽 且 y 是
-0 𝔽 ,则返回 false 。
如果 x 是 -0 𝔽 且 y 是
+0 𝔽 ,则返回 false 。
如果 x 是 y ,则返回 true 。
返回 false 。
6.1.6.1.15 Number::sameValueZero ( x ,
y )
抽象操作 Number::sameValueZero 接受参数 x (一个 Number) 和 y (一个 Number) 并返回一个
Boolean。调用时它执行以下步骤:
如果 x 是 NaN 且 y 是
NaN ,则返回 true 。
如果 x 是 +0 𝔽 且 y 是
-0 𝔽 ,则返回 true 。
如果 x 是 -0 𝔽 且 y 是
+0 𝔽 ,则返回 true 。
如果 x 是 y ,则返回 true 。
返回 false 。
6.1.6.1.16 NumberBitwiseOp ( op , x ,
y )
抽象操作 NumberBitwiseOp 接受参数 op (&、^ 或
|)、x (一个 Number) 和 y (一个 Number) 并返回一个整数
Number 。调用时它执行以下步骤:
令 lNum 为 ! ToInt32 (x )。
令 rNum 为 ! ToInt32 (y )。
令 lBits 为表示 ℝ (lNum ) 的 32 位二进制补码位串。
令 rBits 为表示 ℝ (rNum ) 的 32 位二进制补码位串。
如果 op 是 &,则
令 result 为对 lBits 和 rBits 应用按位与运算的结果。
否则,如果 op 是 ^,则
令 result 为对 lBits 和 rBits 应用按位异或 (XOR)
运算的结果。
否则,
断言 :op 是 |。
令 result 为对 lBits 和 rBits 应用按位或运算的结果。
返回由 32 位二进制补码位串 result 表示的整数 的Number 值 。
6.1.6.1.17 Number::bitwiseAND ( x , y )
抽象操作 Number::bitwiseAND 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个整数
Number 。调用时它执行以下步骤:
返回 NumberBitwiseOp (&,
x , y )。
6.1.6.1.18 Number::bitwiseXOR ( x , y )
抽象操作 Number::bitwiseXOR 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个整数
Number 。调用时它执行以下步骤:
返回 NumberBitwiseOp (^,
x , y )。
6.1.6.1.19 Number::bitwiseOR ( x , y )
抽象操作 Number::bitwiseOR 接受参数 x (一个 Number) 和 y (一个 Number)
并返回一个整数
Number 。调用时它执行以下步骤:
返回 NumberBitwiseOp (|,
x , y )。
6.1.6.1.20 Number::toString ( x , radix
)
抽象操作 Number::toString 接受参数 x (一个 Number) 和 radix (一个闭区间 [2, 36] 内的整数 ) 并返回一个
String。它使用基数为 radix 的位置数字系统将 x 表示为字符串。使用基数 r
表示数字时使用的数字取自 "0123456789abcdefghijklmnopqrstuvwxyz" 的前 r
个代码单元(按顺序)。大小大于或等于 1 𝔽 的数字的表示永远不包含前导零。调用时它执行以下步骤:
如果 x 是 NaN ,则返回 "NaN" 。
如果 x 是 +0 𝔽 或
-0 𝔽 ,则返回 "0" 。
如果 x < -0 𝔽 ,则返回字符串连接 "-"
和 Number::toString (-x ,
radix )。
如果 x 是 +∞ 𝔽 ,则返回
"Infinity" 。
令 n 、k 和
s 为整数 ,使得 k ≥
1,radix k - 1 ≤ s <
radix k ,𝔽 (s ×
radix n - k ) 是 x ,并且
k 尽可能小。注意,k 是使用基数 radix 表示 s
的位数,s 不能被 radix 整除,并且 s 的最低有效位不一定由这些标准唯一确定。
如果 radix ≠ 10 或 n 在闭区间 [-5, 21] 内,则
如果 n ≥ k ,则
返回以下各项的字符串连接 :
使用基数 radix 表示 s 的 k
位数字的代码单元
n - k 个代码单元 0x0030 (DIGIT ZERO)
否则,如果 n > 0,则
返回以下各项的字符串连接 :
使用基数 radix 表示 s 的最高有效 n
位数字的代码单元
代码单元 0x002E (FULL STOP)
使用基数 radix 表示 s 的其余 k -
n 位数字的代码单元
否则,
断言 :n ≤ 0。
返回以下各项的字符串连接 :
代码单元 0x0030 (DIGIT ZERO)
代码单元 0x002E (FULL STOP)
-n 个代码单元 0x0030 (DIGIT ZERO)
使用基数 radix 表示 s 的 k
位数字的代码单元
注意:在这种情况下,输入将使用科学 E 表示法表示,例如 1.2e+3。
断言 :radix 是 10。
如果 n < 0,则
令 exponentSign 为代码单元 0x002D (HYPHEN-MINUS)。
否则,
令 exponentSign 为代码单元 0x002B (PLUS SIGN)。
如果 k = 1,则
返回以下各项的字符串连接 :
s 的单个数字的代码单元
代码单元 0x0065 (LATIN SMALL LETTER E)
exponentSign
abs (n - 1)
的十进制表示的代码单元
返回以下各项的字符串连接 :
s 的十进制表示的最高有效数字的代码单元
代码单元 0x002E (FULL STOP)
s 的十进制表示的其余 k - 1 位数字的代码单元
代码单元 0x0065 (LATIN SMALL LETTER E)
exponentSign
abs (n - 1) 的十进制表示的代码单元
注1
以下观察结果可能对实现有所帮助,但并非本标准的规范性要求的一部分:
注2
对于提供比上述规则要求的转换更精确的实现,建议使用以下步骤 5
的替代版本作为指导:
令 n 、k 和 s 为整数 ,使得 k
≥ 1,radix k - 1 ≤ s <
radix k ,𝔽 (s ×
radix n - k ) 是
x ,并且 k 尽可能小。如果 s 有多种可能性,则选择使
s × radix n - k
的值最接近 ℝ (x ) 的 s
值。如果存在两个这样的 s 可能值,则选择偶数那个。注意,k 是使用基数
radix 表示 s 的位数,并且 s 不能被
radix 整除。
注3
ECMAScript 的实现者可能会发现 David M. Gay 编写的用于浮点数二进制到十进制转换的论文和代码很有用:
Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary Conversions.
Numerical Analysis, Manuscript 90-10. AT&T Bell Laboratories (Murray Hill,
New Jersey). 1990年11月30日。可从以下网址获取:
https://ampl.com/_archive/first-website/REFS/rounding.pdf 。
相关代码可从以下网址获取:
http://netlib.sandia.gov/fp/dtoa.c
和
http://netlib.sandia.gov/fp/g_fmt.c
也可以在各种 netlib 镜像站点找到。
6.1.6.2 BigInt 类型
BigInt 类型 表示一个整数 值。该值可以是任意大小,不限于特定的位宽。一般来说,除非另有说明,操作被设计为返回精确的基于数学的答案。对于二进制操作,BigInt
表现为二进制补码字符串,负数被视为左侧无限设置位。
6.1.6.2.1 BigInt::unaryMinus ( x )
抽象操作 BigInt::unaryMinus 接受参数 x (一个 BigInt)并返回一个 BigInt。调用时执行以下步骤:
如果 x = 0 ℤ ,返回
0 ℤ 。
返回 -x 。
6.1.6.2.2 BigInt::bitwiseNOT ( x )
抽象操作 BigInt::bitwiseNOT 接受参数 x (一个 BigInt)并返回一个 BigInt。它返回 x
的一的补码。调用时执行以下步骤:
返回 -x - 1 ℤ 。
6.1.6.2.3 BigInt::exponentiate ( base ,
exponent )
抽象操作 BigInt::exponentiate 接受参数 base (一个 BigInt)和 exponent (一个
BigInt),返回包含 BigInt
的正常完成或抛出完成 。调用时执行以下步骤:
如果 exponent < 0 ℤ ,抛出
RangeError 异常。
如果 base = 0 ℤ 且 exponent =
0 ℤ ,返回 1 ℤ 。
返回 base 的 exponent 次幂。
6.1.6.2.4 BigInt::multiply ( x , y )
抽象操作 BigInt::multiply 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 x × y 。
注意
即使结果的位宽比输入大得多,也会给出精确的数学答案。
6.1.6.2.5 BigInt::divide ( x , y )
抽象操作 BigInt::divide 接受参数 x (一个 BigInt)和 y (一个 BigInt),返回包含 BigInt
的正常完成或抛出完成 。调用时执行以下步骤:
如果 y = 0 ℤ ,抛出
RangeError 异常。
令 quotient 为 ℝ (x ) / ℝ (y )。
返回 ℤ (truncate (quotient ))。
6.1.6.2.6 BigInt::remainder ( n , d )
抽象操作 BigInt::remainder 接受参数 n (一个 BigInt)和 d (一个 BigInt),返回包含 BigInt
的正常完成或抛出完成 。调用时执行以下步骤:
如果 d = 0 ℤ ,抛出
RangeError 异常。
如果 n = 0 ℤ ,返回
0 ℤ 。
令 quotient 为 ℝ (n ) / ℝ (d )。
令 q 为 ℤ (truncate (quotient ))。
返回 n - (d × q )。
注意
结果的符号是被除数的符号。
6.1.6.2.7 BigInt::add ( x , y )
抽象操作 BigInt::add 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 x + y 。
6.1.6.2.8 BigInt::subtract ( x , y )
抽象操作 BigInt::subtract 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 x - y 。
6.1.6.2.9 BigInt::leftShift ( x , y )
抽象操作 BigInt::leftShift 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
如果 y < 0 ℤ ,则
返回 ℤ (floor (ℝ (x )
/ 2-ℝ (y ) ))。
返回 x × 2 ℤ y 。
注意
这里的语义应该等同于按位移位,将 BigInt 视为无限长度的二进制补码数字字符串。
6.1.6.2.10 BigInt::signedRightShift ( x ,
y )
抽象操作 BigInt::signedRightShift 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 BigInt::leftShift (x ,
-y )。
6.1.6.2.11 BigInt::unsignedRightShift ( x ,
y )
抽象操作 BigInt::unsignedRightShift 接受参数 x (一个 BigInt)和 y (一个
BigInt)并返回抛出完成 。调用时执行以下步骤:
抛出 TypeError 异常。
6.1.6.2.12 BigInt::lessThan ( x , y )
抽象操作 BigInt::lessThan 接受参数 x (一个 BigInt)和 y (一个
BigInt)并返回一个布尔值。调用时执行以下步骤:
如果 ℝ (x )
< ℝ (y ),返回 true ;否则返回
false 。
6.1.6.2.13 BigInt::equal ( x , y )
抽象操作 BigInt::equal 接受参数 x (一个 BigInt)和 y (一个
BigInt)并返回一个布尔值。调用时执行以下步骤:
如果 ℝ (x )
= ℝ (y ),返回 true ;否则返回
false 。
6.1.6.2.14 BinaryAnd ( x , y )
抽象操作 BinaryAnd 接受参数 x (0 或 1)和 y (0 或 1)并返回 0 或 1。调用时执行以下步骤:
如果 x = 1 且 y = 1,返回 1。
否则,返回 0。
6.1.6.2.15 BinaryOr ( x , y )
抽象操作 BinaryOr 接受参数 x (0 或 1)和 y (0 或 1)并返回 0 或 1。调用时执行以下步骤:
如果 x = 1 或 y = 1,返回 1。
否则,返回 0。
6.1.6.2.16 BinaryXor ( x , y )
抽象操作 BinaryXor 接受参数 x (0 或 1)和 y (0 或 1)并返回 0 或 1。调用时执行以下步骤:
如果 x = 1 且 y = 0,返回 1。
否则如果 x = 0 且 y = 1,返回 1。
否则,返回 0。
6.1.6.2.17 BigIntBitwiseOp ( op , x ,
y )
抽象操作 BigIntBitwiseOp 接受参数 op (&、^ 或
|)、x (一个 BigInt)和 y (一个 BigInt)并返回一个 BigInt。调用时执行以下步骤:
设置 x 为 ℝ (x )。
设置 y 为 ℝ (y )。
令 result 为 0。
令 shift 为 0。
重复执行,直到 (x = 0 或 x = -1) 且 (y = 0 或
y = -1):
令 xDigit 为 x modulo 2。
令 yDigit 为 y modulo 2。
如果 op 是 &,则
设置 result 为 result +
2shift × BinaryAnd (xDigit ,
yDigit )。
否则如果 op 是 |,则
设置 result 为 result +
2shift × BinaryOr (xDigit ,
yDigit )。
否则,
断言 :op 是
^。
设置 result 为 result +
2shift × BinaryXor (xDigit ,
yDigit )。
设置 shift 为 shift + 1。
设置 x 为 (x - xDigit ) / 2。
设置 y 为 (y - yDigit ) / 2。
如果 op 是 &,则
令 tmp 为 BinaryAnd (x
modulo 2, y
modulo 2)。
否则如果 op 是 |,则
令 tmp 为 BinaryOr (x
modulo 2, y
modulo 2)。
否则,
断言 :op 是 ^。
令 tmp 为 BinaryXor (x
modulo 2, y
modulo 2)。
如果 tmp ≠ 0,则
设置 result 为 result - 2shift 。
注意:这扩展了符号。
返回 result 的 BigInt 值 。
6.1.6.2.18 BigInt::bitwiseAND ( x , y )
抽象操作 BigInt::bitwiseAND 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 BigIntBitwiseOp (&,
x , y )。
6.1.6.2.19 BigInt::bitwiseXOR ( x , y )
抽象操作 BigInt::bitwiseXOR 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 BigIntBitwiseOp (^,
x , y )。
6.1.6.2.20 BigInt::bitwiseOR ( x , y )
抽象操作 BigInt::bitwiseOR 接受参数 x (一个 BigInt)和 y (一个 BigInt)并返回一个
BigInt。调用时执行以下步骤:
返回 BigIntBitwiseOp (|,
x , y )。
6.1.6.2.21 BigInt::toString ( x , radix
)
抽象操作 BigInt::toString 接受参数 x (一个 BigInt)和 radix (一个在 2 到 36
的闭区间 内的整数 )并返回一个字符串。它使用基数为 radix
的位置记数法将 x 表示为字符串。在基数为 r 的 BigInt 表示中使用的数字取自
"0123456789abcdefghijklmnopqrstuvwxyz" 的前 r 个代码单元。除了
0 ℤ 之外的 BigInt 表示从不包含前导零。调用时执行以下步骤:
如果 x < 0 ℤ ,返回 "-"
和 BigInt::toString (-x ,
radix ) 的字符串连接 。
返回使用基数 radix 表示 x 的字符串值。
6.1.7 Object 类型
Object 类型 的每个实例,也简称为"一个
Object",表示属性的集合。每个属性要么是数据属性,要么是访问器属性:
对象的属性使用属性键 唯一标识。 属性键 要么是字符串,要么是符号。所有字符串和符号(包括空字符串)都可以作为属性键 。属性名 是字符串 类型的属性键 。
整数索引 是属性名 n ,使得 CanonicalNumericIndexString (n )
返回闭区间 从 +0 𝔽 到
𝔽 (253 - 1)
的整数 。数组索引 是整数索引 n ,使得 CanonicalNumericIndexString (n )
返回闭区间 从 +0 𝔽 到
𝔽 (232 - 2)
的整数 。
注意
每个非负安全整数 都有对应的整数索引 。除了 232 - 1 之外的每个 32 位无符号整数 都有对应的数组索引 。"-0" 既不是整数索引 也不是数组索引 。
属性键 用于访问属性及其值。属性有两种访问方式:get 和
set ,分别对应值检索和赋值。通过 get 和 set
访问的属性包括作为对象直接部分的自有属性 和通过属性继承关系由另一个关联对象提供的继承属性 。继承属性可能是关联对象的自有属性或继承属性。对象的每个自有属性都必须具有与该对象的其他自有属性的键值不同的键值。
所有对象在逻辑上都是属性的集合,但存在多种形式的对象,它们在访问和操作属性的语义上有所不同。请参见6.1.7.2 了解多种形式对象的定义。
此外,某些对象是可调用的;这些被称为函数或函数对象 ,下面将进一步描述。ECMAScript 中的所有函数都是 Object 类型的成员。
6.1.7.1 属性特性
本规范使用特性来定义和解释 Object 属性的状态,如表
3 所述。除非明确指定,否则每个特性的初始值是其默认值。
表 3:Object 属性的特性
特性名称
存在该特性的属性类型
值域
默认值
描述
[[Value]]
数据属性
ECMAScript
语言值
undefined
通过对属性的 get 访问检索到的值。
[[Writable]]
数据属性
布尔值
false
如果为 false ,ECMAScript 代码尝试使用 [[Set]] 更改属性的 [[Value]]
特性将不会成功。
[[Get]]
访问器属性
Object 或 undefined
undefined
如果值是一个 Object ,它必须是函数对象 。每当执行对属性的 get
访问时,都会使用空参数列表调用该函数的 [[Call]] 内部方法(表
5 )来检索属性值。
[[Set]]
访问器属性
Object 或 undefined
undefined
如果值是一个 Object ,它必须是函数对象 。每当执行对属性的 set
访问时,都会使用包含赋值作为其唯一参数的参数列表调用该函数的 [[Call]]
内部方法(表
5 )。属性的 [[Set]]
内部方法的效果可能但不一定会影响后续调用属性的 [[Get]] 内部方法返回的值。
[[Enumerable]]
数据属性 或访问器属性
布尔值
false
如果为 true ,该属性将被 for-in 枚举(参见14.7.5 )枚举。否则,该属性被称为不可枚举的。
[[Configurable]]
数据属性 或访问器属性
布尔值
false
如果为 false ,尝试删除属性、将其从数据属性 更改为访问器属性 或从访问器属性 更改为数据属性 ,或对其特性进行任何更改(除了替换现有的
[[Value]] 或将 [[Writable]] 设置为 false )都将失败。
6.1.7.2 对象内部方法和内部槽
在 ECMAScript 中,对象的实际语义通过称为内部方法 的算法指定。ECMAScript 引擎中的每个对象都与一组定义其运行时行为的内部方法相关联。这些内部方法不是
ECMAScript 语言的一部分。它们由本规范纯粹为了解释目的而定义。但是,ECMAScript
实现中的每个对象都必须按照与其关联的内部方法所指定的方式行为。实现这一点的确切方式由实现决定。
内部方法名称是多态的。这意味着当在不同的对象值上调用相同的内部方法名称时,可能执行不同的算法。实际调用内部方法的对象是调用的"目标"。如果在运行时,算法的实现尝试使用对象不支持的内部方法,则抛出
TypeError 异常。
内部槽对应于与对象关联并由各种 ECMAScript 规范算法使用的内部状态。内部槽不是对象属性,它们不被继承。根据特定的内部槽规范,这种状态可能由任何ECMAScript 语言类型 的值或特定 ECMAScript
规范类型值组成。除非明确指定,否则内部槽作为创建对象过程的一部分分配,并且不能动态添加到对象中。除非另有指定,内部槽的初始值是
undefined 。本规范中的各种算法创建具有内部槽的对象。但是,ECMAScript 语言没有提供将内部槽与对象关联的直接方法。
所有对象都有一个名为 [[PrivateElements]] 的内部槽,它是PrivateElements
的列表 。这个列表 表示对象的私有字段、方法和访问器的值。最初,它是一个空列表 。
内部方法和内部槽在本规范中使用双方括号 [[ ]] 括起来的名称标识。
表
4 总结了本规范使用的基本内部方法 ,适用于 ECMAScript
代码创建或操作的所有对象。每个对象都必须具有所有基本内部方法的算法。但是,并非所有对象都必须为这些方法使用相同的算法。
普通对象 是满足以下所有条件的对象:
异质对象 是不是普通对象 的对象。
本规范通过对象的内部方法识别不同种类的异质对象 。行为上等同于特定种类异质对象 (如数组异质对象 或绑定函数异质对象 )但没有为该种类指定的相同内部方法集合的对象,不被识别为该种类的异质对象 。
表
4 和其他类似表的"签名"列描述了每个内部方法的调用模式。调用模式总是包括描述性参数名称的括号列表。如果参数名称与 ECMAScript
类型名称相同,则该名称描述参数值的所需类型。如果内部方法明确返回值,其参数列表后跟符号"→"和返回值的类型名称。签名中使用的类型名称指的是第6 节中定义的类型,并由以下附加名称扩展。"any "意味着该值可能是任何ECMAScript 语言类型 。
除了参数之外,内部方法始终可以访问作为方法调用目标的对象。
内部方法隐式返回完成记录 ,要么是包装其调用模式中显示的返回类型值的正常完成 ,要么是抛出完成 。
表 4:基本内部方法
内部方法
签名
描述
[[GetPrototypeOf]]
( ) → Object | Null
确定为此对象提供继承属性的对象。null 值表示没有继承属性。
[[SetPrototypeOf]]
(Object | Null) → Boolean
将此对象与提供继承属性的另一个对象关联。传递 null 表示没有继承属性。返回
true 表示操作成功完成,或 false 表示操作不成功。
[[IsExtensible]]
( ) → Boolean
确定是否允许向此对象添加额外属性。
[[PreventExtensions]]
( ) → Boolean
控制是否可以向此对象添加新属性。如果操作成功则返回 true ,如果操作不成功则返回
false 。
[[GetOwnProperty]]
(propertyKey ) → Undefined | Property
Descriptor
返回此对象键为 propertyKey 的自有属性的属性描述符 ,如果不存在这样的属性则返回
undefined 。
[[DefineOwnProperty]]
(propertyKey , PropertyDescriptor ) → Boolean
创建或更改键为 propertyKey 的自有属性,使其具有 PropertyDescriptor
描述的状态。如果该属性成功创建/更新则返回 true ,如果无法创建或更新该属性则返回
false 。
[[HasProperty]]
(propertyKey ) → Boolean
返回布尔值,表示此对象是否已经具有键为 propertyKey 的自有或继承属性。
[[Get]]
(propertyKey , Receiver ) → any
从此对象返回键为 propertyKey 的属性值。如果必须执行任何 ECMAScript
代码来检索属性值,Receiver 用作评估代码时的 this 值。
[[Set]]
(propertyKey , value , Receiver ) →
Boolean
将键为 propertyKey 的属性值设置为 value 。如果必须执行任何 ECMAScript
代码来设置属性值,Receiver 用作评估代码时的 this
值。如果属性值已设置则返回 true ,如果无法设置则返回
false 。
[[Delete]]
(propertyKey ) → Boolean
从此对象中删除键为 propertyKey 的自有属性。如果属性未被删除且仍然存在则返回
false 。如果属性已被删除或不存在则返回 true 。
[[OwnPropertyKeys]]
( ) → List
of property keys
返回一个列表 ,其元素是对象的所有自有属性键 。
表
5 总结了可作为函数调用的对象支持的额外基本内部方法。函数对象 是支持 [[Call]] 内部方法的对象。构造器 是支持 [[Construct]] 内部方法的对象。每个支持 [[Construct]] 的对象都必须支持 [[Call]] ;也就是说,每个构造器 都必须是函数对象 。因此,构造器 也可以称为构造器 函数 或构造器 函数对象 。
表 5:函数对象的额外基本内部方法
内部方法
签名
描述
[[Call]]
(any , a List
of any ) → any
执行与此对象关联的代码。通过函数调用表达式调用。内部方法的参数是 this 值和一个列表 ,其元素是通过调用表达式传递给函数的参数。实现此内部方法的对象是可调用的 。
[[Construct]]
(a List
of any , Object) → Object
创建对象。通过 new 操作符或 super
调用调用。内部方法的第一个参数是一个列表 ,其元素是构造器 调用或 super
调用的参数。第二个参数是最初应用 new 操作符的对象。实现此内部方法的对象称为构造器 。函数对象 不一定是构造器 ,这种非构造器 函数对象 没有 [[Construct]] 内部方法。
普通对象 和标准异质对象 的基本内部方法的语义在第10 节中指定。如果实现不支持异质对象 的内部方法的任何指定使用,则在尝试时该使用必须抛出
TypeError 异常。
6.1.7.3 基本内部方法的不变式
ECMAScript 引擎中对象的内部方法必须符合下面指定的不变式列表。本规范中的普通 ECMAScript 对象以及所有标准异质对象 都保持这些不变式。ECMAScript 代理对象通过对 [[ProxyHandler]] 对象上调用的陷阱结果进行运行时检查来维持这些不变式。
任何实现提供的异质对象 也必须为这些对象维持这些不变式。违反这些不变式可能导致 ECMAScript
代码出现不可预测的行为并产生安全问题。但是,违反这些不变式绝不能损害实现的内存安全。
实现不得允许以任何方式规避这些不变式,例如通过提供实现基本内部方法功能但不强制执行其不变式的替代接口。
定义:
内部方法的 目标 是调用内部方法的对象。
如果目标被观察到从其 [[IsExtensible]] 内部方法返回 false ,或从其
[[PreventExtensions]] 内部方法返回 true ,则目标是
不可扩展的 。
不存在的 属性是在不可扩展目标上不作为自有属性存在的属性。
所有对 SameValue 的引用都根据 SameValue
算法的定义。
返回值:
任何内部方法返回的值必须是一个完成记录 ,具有以下之一:
[[Type]] = normal ,[[Target]] = empty ,并且 [[Value]] = 下面为该内部方法显示的"正常返回类型"的值,或
[[Type]] = throw ,[[Target]] = empty ,并且 [[Value]] = 任何ECMAScript
语言值 。
注意 1
[[GetPrototypeOf]] ( )
正常返回类型是 Object 或 Null。
如果目标是不可扩展的,并且 [[GetPrototypeOf]] 返回值 V ,那么将来对 [[GetPrototypeOf]] 的所有调用都应该返回与 V SameValue
相同的值。
注意 2
对象的原型链应该具有有限 长度(即,从任何对象开始,递归地将 [[GetPrototypeOf]] 内部方法应用于其结果最终应该导致值
null )。但是,如果原型链包含任何不使用普通对象 的 [[GetPrototypeOf]] 定义的异质对象 ,则此要求无法作为对象级不变式强制执行。这样的循环原型链在访问对象属性时可能导致无限循环。
[[SetPrototypeOf]] ( V )
正常返回类型是 Boolean。
如果目标是不可扩展的,[[SetPrototypeOf]] 必须返回 false ,除非
V 与目标观察到的 [[GetPrototypeOf]] 值为SameValue 。
[[IsExtensible]] ( )
正常返回类型是 Boolean。
如果 [[IsExtensible]] 返回 false ,将来在目标上的所有 [[IsExtensible]] 调用必须返回 false 。
[[PreventExtensions]] ( )
正常返回类型是 Boolean。
如果 [[PreventExtensions]] 返回 true ,将来在目标上的所有
[[IsExtensible]] 调用必须返回
false ,并且目标现在被视为不可扩展的。
[[GetOwnProperty]] ( P )
正常返回类型是属性描述符 或
Undefined。
如果返回值是属性描述符 ,它必须是一个完全填充的属性描述符 。
如果 P 被描述为不可配置、不可写的自有数据属性 ,将来对 [[GetOwnProperty]] ( P ) 的所有调用必须返回其 [[Value]] 与 P 的 [[Value]]
特性为SameValue 的属性描述符 。
如果 P 的除 [[Writable]] 和 [[Value]] 之外的特性可能随时间改变,或者属性可能被删除,那么 P 的 [[Configurable]] 特性必须是 true 。
如果 [[Writable]] 特性可能从 false 变为
true ,那么 [[Configurable]] 特性必须是
true 。
如果目标是不可扩展的并且 P 是不存在的,那么将来在目标上对 [[GetOwnProperty]]
(P ) 的所有调用必须将 P 描述为不存在的(即 [[GetOwnProperty]] (P ) 必须返回
undefined )。
注意 3
作为第三个不变式的结果,如果属性被描述为数据属性 并且它可能随时间返回不同的值,那么 [[Writable]] 和 [[Configurable]]
特性中的一个或两个必须是 true ,即使没有通过其他基本内部方法暴露改变值的机制。
[[DefineOwnProperty]] ( P , Desc )
正常返回类型是 Boolean。
如果 P 之前被观察为目标的不可配置自有属性,那么 [[DefineOwnProperty]] 必须返回
false ,除非以下之一:
P 是可写的数据属性 。不可配置的可写数据属性 可以更改为不可配置的不可写数据属性 。
Desc 的所有特性都与 P 的特性为SameValue 。
如果目标是不可扩展的并且 P 是不存在的自有属性,那么 [[DefineOwnProperty]]
(P , Desc ) 必须返回 false 。也就是说,不可扩展的目标对象不能用新属性扩展。
[[HasProperty]] ( P )
正常返回类型是 Boolean。
如果 P 之前被观察为目标的不可配置自有数据或访问器属性 ,那么 [[HasProperty]] 必须返回 true 。
[[Get]] ( P , Receiver )
正常返回类型是任何ECMAScript 语言类型 。
如果 P 之前被观察为目标的值为 V 的不可配置、不可写的自有数据属性 ,那么 [[Get]] 必须返回与 V SameValue 相同的值。
如果 P 之前被观察为目标的 [[Get]] 特性为
undefined 的不可配置自有访问器属性 ,那么 [[Get]]
操作必须返回 undefined 。
[[Set]] ( P , V , Receiver )
正常返回类型是 Boolean。
如果 P 之前被观察为目标的不可配置、不可写的自有数据属性 ,那么 [[Set]]
必须返回 false ,除非 V 与 P 的 [[Value]] 特性为SameValue 。
如果 P 之前被观察为目标的 [[Set]] 特性为
undefined 的不可配置自有访问器属性 ,那么 [[Set]]
操作必须返回 false 。
[[Delete]] ( P )
正常返回类型是 Boolean。
如果 P 之前被观察为目标的不可配置自有数据或访问器属性 ,那么 [[Delete]] 必须返回 false 。
[[OwnPropertyKeys]] ( )
正常返回类型是列表 。
返回的列表 不得包含任何重复条目。
返回的列表 的每个元素必须是属性键 。
返回的列表 必须至少包含所有之前被观察到的不可配置自有属性的键。
如果目标是不可扩展的,返回的列表 必须只包含使用 [[GetOwnProperty]] 可观察到的目标的所有自有属性的键。
[[Call]] ( )
[[Construct]] ( )
正常返回类型是 Object。
目标也必须有一个 [[Call]] 内部方法。
6.1.7.4 知名内置对象
知名内置对象是被本规范算法明确引用的内置对象,通常具有域 特定的标识。除非另有说明,每个内置对象实际上对应一组相似的对象,每个域 一个。
在本规范中,像 %name% 这样的引用意味着与当前域 关联的、对应于该名称的内置对象。像 %name.a.b% 这样的引用意味着,就像在任何 ECMAScript
代码被评估之前访问内置对象 %name% 的 "a" 属性的值的 "b" 属性一样。当前域 及其内置对象的确定在9.4 中描述。知名内置对象列在表 6 中。
表 6:知名内置对象
注意
6.2 ECMAScript 规范类型
规范类型对应于在算法中用于描述 ECMAScript 语言构造和ECMAScript 语言类型 语义的元值。规范类型包括引用记录 、列表 、完成记录 、属性描述符 、环境记录 、抽象闭包 和数据块 。规范类型值是规范工件,不一定对应于 ECMAScript
实现中的任何特定实体。规范类型值可用于描述 ECMAScript 表达式求值的中间结果,但此类值不能存储为对象的属性或 ECMAScript 语言变量的值。
6.2.1 枚举规范类型
枚举 是规范内部的值,不能从 ECMAScript
代码直接观察到。枚举使用无衬线 字体表示。例如,完成记录 的 [[Type]] 字段取值如
normal 、return 或
throw 。枚举除了名称之外没有其他特征。枚举的名称除了将其与其他枚举区分开来之外没有其他目的,并且不暗示其在上下文中的用法或含义。
6.2.2 列表和记录规范类型
列表 类型用于解释 new
表达式、函数调用和其他需要简单有序值列表的算法中参数列表的求值(参见13.3.8 )。列表类型的值只是包含各个值的列表元素的有序序列。这些序列可以是任意长度。列表的元素可以使用从
0 开始的索引随机访问。为了方便表示,可以使用类似数组的语法来访问列表元素。例如,arguments [2] 是表示列表 arguments 第 3
个元素的简写。
当算法遍历列表的元素而不指定顺序时,使用的顺序是列表中元素的顺序。
为了在本规范中方便表示,可以使用字面量语法来表达新的列表值。例如,« 1, 2 » 定义了一个有两个元素的列表值,每个元素都初始化为特定值。新的空列表可以表示为 « »。
在本规范中,短语"A 、B 、... 的列表连接 "(其中每个参数都是可能为空的列表)表示一个新的列表值,其元素是每个参数的元素(按顺序)的连接(按顺序)。
当应用于字符串列表时,短语"按字典序码元顺序 排序"意味着按每个码元的数值排序,直到较短字符串的长度,如果所有都相等,则较短的字符串排在较长的字符串之前,如抽象操作IsLessThan 中所述。
记录 类型用于描述本规范算法中的数据聚合。记录类型值由一个或多个命名字段组成。每个字段的值是ECMAScript 语言值 或规范值。字段名总是用双括号括起来,例如
[[Value]] 。
为了在本规范中方便表示,可以使用类似对象字面量的语法来表达记录值。例如,{ [[Field1]] : 42, [[Field2]] : false , [[Field3]] : empty }
定义了一个有三个字段的记录值,每个字段都初始化为特定值。字段名顺序不重要。任何未明确列出的字段都被认为是缺失的。
在规范文本和算法中,可以使用点记法来引用记录值的特定字段。例如,如果 R 是前一段中显示的记录,那么 R.[[Field2]] 是"R 中名为
[[Field2]] 的字段"的简写。
常用记录字段组合的模式可以被命名,该名称可以用作字面量记录值的前缀,以标识所描述的特定类型的聚合。例如:PropertyDescriptor { [[Value]] : 42, [[Writable]] :
false , [[Configurable]] : true }。
6.2.3 集合和关系规范类型
集合 类型用于解释在内存模型 中使用的无序元素集合。它不同于同名的 ECMAScript
集合类型。为了消除歧义,ECMAScript 集合的实例在本规范中始终称为"Set
对象"。集合类型的值是元素的简单集合,其中没有元素出现超过一次。元素可以添加到集合中或从集合中移除。集合可以进行并集、交集或相减操作。
关系 类型用于解释对集合的约束。关系类型的值是其值域中值的有序对的集合。例如,事件上的关系是事件有序对的集合。对于关系 R
和 R 值域中的两个值 a 和 b ,a R b 是说有序对
(a , b ) 是 R 的成员的简写。关系是相对于某些条件的最小关系 ,当它是满足这些条件的最小关系时。
严格偏序 是满足以下条件的关系值 R 。
对于 R 域中的所有 a 、b 和 c :
a R a 不成立,并且
如果 a R b 且 b R
c ,那么 a R c 。
注意 1
严格全序 是满足以下条件的关系值 R 。
对于 R 域中的所有 a 、b 和 c :
a 是 b 或 a R b 或 b
R a ,并且
a R a 不成立,并且
如果 a R b 且 b R
c ,那么 a R c 。
注意 2
6.2.4 完成记录规范类型
完成记录 规范类型用于解释值和控制流的运行时传播,例如执行非本地控制转移的语句(break、continue、return
和 throw)的行为。
完成记录具有表 7 中定义的字段。
表 7:完成记录 字段
字段名
值
含义
[[Type]]
normal 、break 、continue 、return
或 throw
发生的完成类型。
[[Value]]
除完成记录 之外的任何值
产生的值。
[[Target]]
一个字符串或 empty
定向控制转移的目标标签。
以下简写术语有时用于指代完成记录。
正常完成 指任何 [[Type]] 值为 normal 的完成记录。
break 完成 指任何 [[Type]] 值为 break 的完成记录。
continue 完成 指任何 [[Type]] 值为 continue 的完成记录。
return 完成 指任何 [[Type]] 值为 return 的完成记录。
throw 完成 指任何 [[Type]] 值为 throw 的完成记录。
突然完成 指任何 [[Type]] 值不是 normal 的完成记录。
包含某种类型值的正常完成 指在其 [[Value]] 字段中具有该类型值的正常完成。
本规范中定义的可调用对象只返回正常完成或 throw 完成。返回任何其他类型的完成记录被认为是编辑错误。
实现定义的 可调用对象必须返回正常完成或 throw 完成。
6.2.4.1 NormalCompletion ( value )
抽象操作 NormalCompletion 接受参数 value (除完成记录 之外的任何值)并返回一个正常完成 。它在被调用时执行以下步骤:
返回完成记录 { [[Type]] : normal , [[Value]] : value , [[Target]] : empty }。
6.2.4.2 ThrowCompletion ( value )
抽象操作 ThrowCompletion 接受参数 value (一个ECMAScript
语言值 )并返回一个throw
完成 。它在被调用时执行以下步骤:
返回完成记录 { [[Type]] : throw , [[Value]] : value , [[Target]] : empty }。
6.2.4.3 ReturnCompletion ( value )
抽象操作 ReturnCompletion 接受参数 value (一个ECMAScript
语言值 )并返回一个return
完成 。它在被调用时执行以下步骤:
返回完成记录 { [[Type]] : return , [[Value]] : value , [[Target]] : empty }。
6.2.4.4 UpdateEmpty ( completionRecord ,
value )
抽象操作 UpdateEmpty 接受参数 completionRecord (一个完成记录 )和
value (除完成记录 之外的任何值)并返回一个完成记录 。它在被调用时执行以下步骤:
断言 :如果
completionRecord 是return
完成 或throw
完成 ,那么 completionRecord .[[Value]] 不是 empty 。
如果 completionRecord .[[Value]] 不是
empty ,返回 ? completionRecord 。
返回完成记录 { [[Type]] : completionRecord .[[Type]] , [[Value]] :
value , [[Target]] :
completionRecord .[[Target]] }。
6.2.5 引用记录规范类型
引用记录 类型用于解释诸如
delete、typeof、赋值运算符、super 关键字 和其他语言特性的行为。例如,赋值的左操作数应该产生一个引用记录。
引用记录是一个已解析的名称或(可能尚未解析的)属性绑定;其字段由表 8 定义。
表 8:引用记录 字段
本规范中使用以下抽象操作 来操作引用记录:
6.2.5.1 IsPropertyReference ( V )
抽象操作 IsPropertyReference 接受参数 V (一个引用记录 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 V .[[Base]] 是
unresolvable ,返回 false 。
如果 V .[[Base]] 是环境记录 ,返回
false ;否则返回 true 。
6.2.5.2 IsUnresolvableReference ( V )
抽象操作 IsUnresolvableReference 接受参数 V (一个引用记录 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 V .[[Base]] 是
unresolvable ,返回 true ;否则返回
false 。
6.2.5.3 IsSuperReference ( V )
抽象操作 IsSuperReference 接受参数 V (一个引用记录 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 V .[[ThisValue]] 不是
empty ,返回 true ;否则返回
false 。
6.2.5.4 IsPrivateReference ( V )
抽象操作 IsPrivateReference 接受参数 V (一个引用记录 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 V .[[ReferencedName]] 是私有名称 ,返回
true ;否则返回 false 。
6.2.5.5 GetValue ( V )
抽象操作 GetValue 接受参数 V (一个引用记录 或一个ECMAScript 语言值 )并返回一个包含 ECMAScript 语言值 的正常完成 或一个突然完成 。它在被调用时执行以下步骤:
如果 V 不是引用记录 ,返回
V 。
如果IsUnresolvableReference (V )
是 true ,抛出 ReferenceError 异常。
如果IsPropertyReference (V )
是 true ,那么
设 baseObj 为 ? ToObject (V .[[Base]] )。
如果IsPrivateReference (V )
是 true ,那么
返回 ? PrivateGet (baseObj ,
V .[[ReferencedName]] )。
如果 V .[[ReferencedName]] 不是属性键 ,那么
设 V .[[ReferencedName]] 为
? ToPropertyKey (V .[[ReferencedName]] )。
返回 ? baseObj .[[Get]] (V .[[ReferencedName]] , GetThisValue (V ))。
否则,
设 base 为 V .[[Base]] 。
断言 :base 是环境记录 。
返回 ? base .GetBindingValue (V .[[ReferencedName]] , V .[[Strict]] )(参见9.1 )。
注意
在步骤3.a 中可能创建的对象在上述抽象操作和普通对象 的 [[Get]] 内部方法之外是不可访问的。实现可能选择避免实际创建该对象。
6.2.5.6 PutValue ( V , W )
抽象操作 PutValue 接受参数 V (一个引用记录 或一个ECMAScript 语言值 )和
W (一个ECMAScript 语言值 )并返回一个包含
unused 的正常完成 或一个突然完成 。它在被调用时执行以下步骤:
如果 V 不是引用记录 ,抛出
ReferenceError 异常。
如果IsUnresolvableReference (V )
是 true ,那么
如果 V .[[Strict]] 是
true ,抛出 ReferenceError 异常。
设 globalObj 为GetGlobalObject ()。
执行 ? Set (globalObj ,
V .[[ReferencedName]] , W ,
false )。
返回 unused 。
如果IsPropertyReference (V )
是 true ,那么
设 baseObj 为 ? ToObject (V .[[Base]] )。
如果IsPrivateReference (V )
是 true ,那么
返回 ? PrivateSet (baseObj ,
V .[[ReferencedName]] ,
W )。
如果 V .[[ReferencedName]] 不是属性键 ,那么
设 V .[[ReferencedName]] 为
? ToPropertyKey (V .[[ReferencedName]] )。
设 succeeded 为 ? baseObj .[[Set]] (V .[[ReferencedName]] , W , GetThisValue (V ))。
如果 succeeded 是 false 且 V .[[Strict]] 是 true ,抛出
TypeError 异常。
返回 unused 。
否则,
设 base 为 V .[[Base]] 。
断言 :base 是环境记录 。
返回 ? base .SetMutableBinding (V .[[ReferencedName]] , W , V .[[Strict]] )(参见9.1 )。
注意
在步骤3.a 中可能创建的对象在上述抽象操作和普通对象 的 [[Set]] 内部方法之外是不可访问的。实现可能选择避免实际创建该对象。
6.2.5.7 GetThisValue ( V )
抽象操作 GetThisValue 接受参数 V (一个引用记录 )并返回一个ECMAScript 语言值 。它在被调用时执行以下步骤:
断言 :IsPropertyReference (V )
是 true 。
如果IsSuperReference (V ) 是
true ,返回 V .[[ThisValue]] ;否则返回
V .[[Base]] 。
6.2.5.8 InitializeReferencedBinding ( V , W
)
抽象操作 InitializeReferencedBinding 接受参数 V (一个引用记录 )和
W (一个ECMAScript 语言值 )并返回一个包含
unused 的正常完成 或一个突然完成 。它在被调用时执行以下步骤:
断言 :IsUnresolvableReference (V )
是 false 。
设 base 为 V .[[Base]] 。
断言 :base 是环境记录 。
返回 ? base .InitializeBinding(V .[[ReferencedName]] , W )。
6.2.5.9 MakePrivateReference ( baseValue ,
privateIdentifier )
抽象操作 MakePrivateReference 接受参数 baseValue (一个ECMAScript 语言值 )和
privateIdentifier (一个字符串)并返回一个引用记录 。它在被调用时执行以下步骤:
设 privateEnv 为运行执行上下文 的
PrivateEnvironment。
断言 :privateEnv 不是
null 。
设 privateName 为ResolvePrivateIdentifier (privateEnv ,
privateIdentifier )。
返回引用记录 { [[Base]] : baseValue , [[ReferencedName]] : privateName , [[Strict]] : true , [[ThisValue]] : empty }。
6.2.6 属性描述符规范类型
属性描述符 类型用于解释对象属性特性的操作和具体化。属性描述符是一个具有零个或多个字段的记录 ,其中每个字段的名称是一个特性名称,其值是6.1.7.1 中指定的相应特性值。本规范中用于标记属性描述符记录字面量描述的模式名称是"PropertyDescriptor"。
属性描述符值可以根据某些字段的存在或使用进一步分类为数据属性描述符和访问器属性描述符。数据属性描述符是包含名为 [[Value]] 或 [[Writable]] 的任何字段的描述符。访问器属性描述符是包含名为 [[Get]] 或
[[Set]] 的任何字段的描述符。任何属性描述符都可以有名为 [[Enumerable]]
和 [[Configurable]]
的字段。属性描述符值不能既是数据属性描述符又是访问器属性描述符;但是,它可以两者都不是(在这种情况下它是通用属性描述符)。完全填充的属性描述符 是访问器属性描述符或数据属性描述符,并且具有表 3 中定义的所有相应字段。
本规范中使用以下抽象操作 来操作属性描述符值:
6.2.6.1 IsAccessorDescriptor ( Desc )
抽象操作 IsAccessorDescriptor 接受参数 Desc (一个属性描述符 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 Desc 有 [[Get]] 字段,返回 true 。
如果 Desc 有 [[Set]] 字段,返回 true 。
返回 false 。
6.2.6.2 IsDataDescriptor ( Desc )
抽象操作 IsDataDescriptor 接受参数 Desc (一个属性描述符 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 Desc 有 [[Value]] 字段,返回
true 。
如果 Desc 有 [[Writable]] 字段,返回
true 。
返回 false 。
6.2.6.3 IsGenericDescriptor ( Desc )
抽象操作 IsGenericDescriptor 接受参数 Desc (一个属性描述符 )并返回一个布尔值。它在被调用时执行以下步骤:
如果IsAccessorDescriptor (Desc )
是 true ,返回 false 。
如果IsDataDescriptor (Desc )
是 true ,返回 false 。
返回 true 。
6.2.6.4 FromPropertyDescriptor ( Desc )
抽象操作 FromPropertyDescriptor 接受参数 Desc (一个属性描述符 或
undefined )并返回一个对象或 undefined 。它在被调用时执行以下步骤:
如果 Desc 是 undefined ,返回 undefined 。
设 obj 为OrdinaryObjectCreate (%Object.prototype% )。
断言 :obj 是一个可扩展的普通对象 ,没有自有属性。
如果 Desc 有 [[Value]] 字段,那么
执行 ! CreateDataPropertyOrThrow (obj ,
"value" , Desc .[[Value]] )。
如果 Desc 有 [[Writable]] 字段,那么
执行 ! CreateDataPropertyOrThrow (obj ,
"writable" , Desc .[[Writable]] )。
如果 Desc 有 [[Get]] 字段,那么
执行 ! CreateDataPropertyOrThrow (obj ,
"get" , Desc .[[Get]] )。
如果 Desc 有 [[Set]] 字段,那么
执行 ! CreateDataPropertyOrThrow (obj ,
"set" , Desc .[[Set]] )。
如果 Desc 有 [[Enumerable]] 字段,那么
执行 ! CreateDataPropertyOrThrow (obj ,
"enumerable" , Desc .[[Enumerable]] )。
如果 Desc 有 [[Configurable]] 字段,那么
执行 ! CreateDataPropertyOrThrow (obj ,
"configurable" , Desc .[[Configurable]] )。
返回 obj 。
6.2.6.5 ToPropertyDescriptor ( Obj )
抽象操作 ToPropertyDescriptor 接受参数 Obj (一个ECMAScript 语言值 )并返回一个包含 属性描述符 的正常完成 或一个throw
完成 。它在被调用时执行以下步骤:
如果 Obj 不是对象 ,抛出 TypeError
异常。
设 desc 为一个新的属性描述符 ,初始时没有字段。
设 hasEnumerable 为 ? HasProperty (Obj ,
"enumerable" )。
如果 hasEnumerable 是 true ,那么
设 enumerable 为ToBoolean (? Get (Obj ,
"enumerable" ))。
设 desc .[[Enumerable]] 为
enumerable 。
设 hasConfigurable 为 ? HasProperty (Obj ,
"configurable" )。
如果 hasConfigurable 是 true ,那么
设 configurable 为ToBoolean (? Get (Obj ,
"configurable" ))。
设 desc .[[Configurable]] 为
configurable 。
设 hasValue 为 ? HasProperty (Obj ,
"value" )。
如果 hasValue 是 true ,那么
设 value 为 ? Get (Obj ,
"value" )。
设 desc .[[Value]] 为 value 。
设 hasWritable 为 ? HasProperty (Obj ,
"writable" )。
如果 hasWritable 是 true ,那么
设 writable 为ToBoolean (? Get (Obj ,
"writable" ))。
设 desc .[[Writable]] 为
writable 。
设 hasGet 为 ? HasProperty (Obj ,
"get" )。
如果 hasGet 是 true ,那么
设 getter 为 ? Get (Obj ,
"get" )。
如果IsCallable (getter )
是 false 且 getter 不是
undefined ,抛出 TypeError 异常。
设 desc .[[Get]] 为 getter 。
设 hasSet 为 ? HasProperty (Obj ,
"set" )。
如果 hasSet 是 true ,那么
设 setter 为 ? Get (Obj ,
"set" )。
如果IsCallable (setter )
是 false 且 setter 不是
undefined ,抛出 TypeError 异常。
设 desc .[[Set]] 为 setter 。
如果 desc 有 [[Get]] 字段或 desc 有 [[Set]] 字段,那么
如果 desc 有 [[Value]] 字段或 desc
有 [[Writable]] 字段,抛出 TypeError
异常。
返回 desc 。
6.2.6.6 CompletePropertyDescriptor ( Desc )
抽象操作 CompletePropertyDescriptor 接受参数 Desc (一个属性描述符 )并返回
unused 。它在被调用时执行以下步骤:
设 like 为记录 { [[Value]] : undefined , [[Writable]] : false , [[Get]] : undefined , [[Set]] : undefined , [[Enumerable]] : false , [[Configurable]] : false }。
如果IsGenericDescriptor (Desc )
是 true 或IsDataDescriptor (Desc )
是 true ,那么
如果 Desc 没有 [[Value]] 字段,设
Desc .[[Value]] 为 like .[[Value]] 。
如果 Desc 没有 [[Writable]] 字段,设
Desc .[[Writable]] 为 like .[[Writable]] 。
否则,
如果 Desc 没有 [[Get]] 字段,设
Desc .[[Get]] 为 like .[[Get]] 。
如果 Desc 没有 [[Set]] 字段,设
Desc .[[Set]] 为 like .[[Set]] 。
如果 Desc 没有 [[Enumerable]] 字段,设
Desc .[[Enumerable]] 为 like .[[Enumerable]] 。
如果 Desc 没有 [[Configurable]] 字段,设
Desc .[[Configurable]] 为 like .[[Configurable]] 。
返回 unused 。
6.2.7 环境记录规范类型
环境记录 类型用于解释嵌套函数和块中名称解析的行为。此类型及其操作在9.1 中定义。
6.2.8 抽象闭包规范类型
抽象闭包 规范类型用于引用算法步骤以及一系列值。抽象闭包是元值,使用函数调用样式调用,例如
closure (arg1 , arg2 )。与抽象操作 类似,调用执行抽象闭包描述的算法步骤。
在创建抽象闭包的算法步骤中,值使用动词"capture"后跟别名列表来捕获。当创建抽象闭包时,它捕获当时与每个别名关联的值。在指定调用抽象闭包时要执行的算法的步骤中,每个捕获的值都通过用于捕获该值的别名来引用。
如果抽象闭包返回完成记录 ,该完成记录 必须是正常完成 或throw 完成 。
抽象闭包作为其他算法的一部分内联创建,如以下示例所示。
设 addend 为 41。
设 closure 为一个新的抽象闭包 ,参数为 (x ),捕获
addend 并在调用时执行以下步骤:
返回 x + addend 。
设 val 为 closure (1)。
断言 :val 是 42。
6.2.9 数据块
数据块 规范类型用于描述一个不同且可变的字节大小(8位)数值序列。字节值 是闭区间 从 0 到 255 的整数 。数据块值使用固定数量的字节创建,每个字节的初始值为 0。
为了在本规范中表示方便,可以使用类似数组的语法来访问数据块值的各个字节。此表示法将数据块值表示为基于 0 的整数索引 字节序列。例如,如果
db 是一个 5 字节的数据块值,则可以使用 db [2] 来访问其第 3 个字节。
驻留在内存中且可以被多个代理 并发引用的数据块被指定为共享数据块 。共享数据块具有一个标识(用于相等性测试共享数据块值的目的),该标识是地址无关的 :它不与块在任何进程中映射到的虚拟地址绑定,而是与块表示的内存位置集合绑定。两个数据块仅在它们包含的位置集合相等时才相等;否则,它们不相等,且它们包含的位置集合的交集为空。最后,共享数据块可以与数据块区分开来。
共享数据块的语义通过内存模型 使用共享数据块事件 定义。下面的抽象操作 引入共享数据块事件 ,并作为评估语义和内存模型 事件语义之间的接口。这些事件形成一个候选执行 ,内存模型 对其起过滤器作用。请参考内存模型 以获取完整语义。
共享数据块事件 由内存模型 中定义的记录 建模。
本规范中使用以下抽象操作 来操作数据块值:
6.2.9.1 CreateByteDataBlock ( size )
抽象操作 CreateByteDataBlock 接受参数 size (一个非负整数 )并返回一个包含 数据块 的正常完成 或一个throw
完成 。它在被调用时执行以下步骤:
如果 size > 253 - 1,抛出 RangeError 异常。
设 db 为一个新的数据块 值,由 size
个字节组成。如果无法创建这样的数据块 ,抛出 RangeError
异常。
将 db 的所有字节设置为 0。
返回 db 。
6.2.9.2 CreateSharedByteDataBlock ( size )
抽象操作 CreateSharedByteDataBlock 接受参数 size (一个非负整数 )并返回一个包含 共享数据块 的正常完成 或一个throw
完成 。它在被调用时执行以下步骤:
设 db 为一个新的共享数据块 值,由 size
个字节组成。如果无法创建这样的共享数据块 ,抛出
RangeError 异常。
设 execution 为周围代理 的代理记录 的 [[CandidateExecution]] 字段。
设 eventsRecord 为 execution .[[EventsRecords]] 中 [[AgentSignifier]] 为AgentSignifier ()
的代理事件记录 。
设 zero 为 « 0 »。
对于 db 的每个索引 i ,执行
将WriteSharedMemory
{ [[Order]] : init , [[NoTear]] : true , [[Block]] : db , [[ByteIndex]] : i , [[ElementSize]] : 1, [[Payload]] : zero } 追加到
eventsRecord .[[EventList]] 。
返回 db 。
6.2.9.3 CopyDataBlockBytes ( toBlock ,
toIndex , fromBlock , fromIndex , count )
抽象操作 CopyDataBlockBytes 接受参数 toBlock (一个数据块 或一个共享数据块 )、toIndex (一个非负整数 )、fromBlock (一个数据块 或一个共享数据块 )、fromIndex (一个非负整数 )和
count (一个非负整数 )并返回 unused 。它在被调用时执行以下步骤:
断言 :fromBlock 和 toBlock
是不同的值。
设 fromSize 为 fromBlock 中的字节数。
断言 :fromIndex + count ≤
fromSize 。
设 toSize 为 toBlock 中的字节数。
断言 :toIndex + count ≤
toSize 。
重复,当 count > 0 时,
如果 fromBlock 是共享数据块 ,那么
设 execution 为周围代理 的代理记录 的 [[CandidateExecution]] 字段。
设 eventsRecord 为 execution .[[EventsRecords]] 中 [[AgentSignifier]] 为AgentSignifier ()
的代理事件记录 。
设 bytes 为一个列表 ,其唯一元素是一个非确定性选择的字节值 。
注意:在实现中,bytes 是底层硬件上非原子读取指令的结果。非确定性是内存模型 对描述弱一致性硬件可观察行为的语义规定。
设 readEvent 为ReadSharedMemory
{ [[Order]] :
unordered , [[NoTear]] : true , [[Block]] : fromBlock , [[ByteIndex]] : fromIndex , [[ElementSize]] : 1 }。
将 readEvent 追加到 eventsRecord .[[EventList]] 。
将选择值记录 { [[Event]] : readEvent , [[ChosenValue]] : bytes } 追加到
execution .[[ChosenValues]] 。
如果 toBlock 是共享数据块 ,那么
将WriteSharedMemory
{ [[Order]] :
unordered , [[NoTear]] : true ,
[[Block]] : toBlock , [[ByteIndex]] : toIndex ,
[[ElementSize]] : 1, [[Payload]] : bytes }
追加到 eventsRecord .[[EventList]] 。
否则,
设 toBlock [toIndex ] 为
bytes [0]。
否则,
断言 :toBlock
不是共享数据块 。
设 toBlock [toIndex ] 为
fromBlock [fromIndex ]。
设 toIndex 为 toIndex + 1。
设 fromIndex 为 fromIndex + 1。
设 count 为 count - 1。
返回 unused 。
6.2.10 PrivateElement 规范类型
PrivateElement 类型是一个记录 ,用于私有类字段、方法和访问器的规范。虽然属性描述符 不用于私有元素,但私有字段的行为类似于不可配置、不可枚举、可写的数据属性 ,私有方法的行为类似于不可配置、不可枚举、不可写的数据属性 ,私有访问器的行为类似于不可配置、不可枚举的访问器属性 。
PrivateElement 类型的值是记录 值,其字段由表
9 定义。这些值被称为PrivateElement 。
表 9:PrivateElement 字段
字段名
出现该字段的 [[Kind]] 字段值
值
含义
[[Key]]
全部
一个私有名称
字段、方法或访问器的名称。
[[Kind]]
全部
field 、method 或
accessor
元素的类型。
[[Value]]
field 和 method
一个ECMAScript 语言值
字段的值。
[[Get]]
accessor
一个函数对象 或
undefined
私有访问器的 getter。
[[Set]]
accessor
一个函数对象 或
undefined
私有访问器的 setter。
6.2.11 ClassFieldDefinition 记录规范类型
ClassFieldDefinition 类型是一个记录 ,用于类字段的规范。
ClassFieldDefinition 类型的值是记录 值,其字段由表 10 定义。这些值被称为ClassFieldDefinition 记录 。
表 10:ClassFieldDefinition
记录 字段
字段名
值
含义
[[Name]]
一个私有名称 、字符串或符号
字段的名称。
[[Initializer]]
一个 ECMAScript 函数对象 或
empty
字段的初始化器(如果有)。
6.2.12 私有名称
私有名称 规范类型用于描述一个全局唯一值(即使与其他私有名称在其他方面无法区分,该值也与任何其他私有名称不同),它表示私有类元素(字段、方法或访问器)的键。每个私有名称都有一个关联的不可变
[[Description]] ,它是一个字符串 值。私有名称可以通过PrivateFieldAdd 或PrivateMethodOrAccessorAdd 安装在任何
ECMAScript 对象上,然后使用PrivateGet 和PrivateSet 进行读取或写入。
6.2.13 ClassStaticBlockDefinition 记录规范类型
ClassStaticBlockDefinition
记录 是一个记录 值,用于封装类静态初始化块的可执行代码。
ClassStaticBlockDefinition 记录具有表
11 中列出的字段。
表 11:ClassStaticBlockDefinition
记录 字段
字段名
值
含义
[[BodyFunction]]
一个 ECMAScript 函数对象
在类的静态初始化期间要调用的函数对象 。
7 抽象操作
这些操作不是 ECMAScript 语言的一部分;定义它们仅是为了帮助说明 ECMAScript 语言的语义。其他更专门的抽象操作 在本规范中都有定义。
7.1 类型转换
ECMAScript 语言根据需要隐式执行自动类型转换。为了阐明某些构造的语义,定义一组转换抽象操作 是有用的。转换抽象操作 是多态的;它们可以接受任何ECMAScript 语言类型 的值。但这些操作不使用其他规范类型。
BigInt 类型 在 ECMAScript
语言中没有隐式转换;程序员必须显式调用 BigInt 来将值从其他类型转换。
7.1.1 ToPrimitive ( input [ , preferredType ]
)
抽象操作 ToPrimitive 接受参数 input (一个ECMAScript 语言值 )和可选参数
preferredType (string 或
number )并返回一个包含 ECMAScript 语言值 的正常完成 或一个throw 完成 。它将其
input 参数转换为非对象类型 。如果对象能够转换为多个原始类型,它可以使用可选提示
preferredType 来偏向该类型。它在被调用时执行以下步骤:
如果 input 是对象 ,那么
设 exoticToPrim 为 ? GetMethod (input , %Symbol.toPrimitive% )。
如果 exoticToPrim 不是 undefined ,那么
如果 preferredType 不存在,那么
设 hint 为 "default" 。
否则如果 preferredType 是 string ,那么
设 hint 为 "string" 。
否则,
断言 :preferredType
是 number 。
设 hint 为 "number" 。
设 result 为 ? Call (exoticToPrim ,
input , « hint »)。
如果 result 不是对象 ,返回
result 。
抛出 TypeError 异常。
如果 preferredType 不存在,设 preferredType 为
number 。
返回 ? OrdinaryToPrimitive (input ,
preferredType )。
返回 input 。
注意
当调用 ToPrimitive 时不带提示,那么它通常表现为提示是 number 。但是,对象可以通过定义 %Symbol.toPrimitive%
方法来覆盖此行为。在本规范中定义的对象中,只有 Date(参见 21.4.4.45 )和
Symbol 对象(参见 20.4.3.5 )覆盖默认的
ToPrimitive 行为。Date 将提示的缺失视为提示是 string 。
7.1.1.1 OrdinaryToPrimitive ( O , hint )
抽象操作 OrdinaryToPrimitive 接受参数 O (一个对象)和
hint (string 或 number )并返回一个包含 ECMAScript 语言值 的正常完成 或一个throw
完成 。它在被调用时执行以下步骤:
如果 hint 是 string ,那么
设 methodNames 为 « "toString" ,
"valueOf" »。
否则,
设 methodNames 为 « "valueOf" ,
"toString" »。
对于 methodNames 的每个元素 name ,执行
设 method 为 ? Get (O ,
name )。
如果 IsCallable (method )
是 true ,那么
设 result 为 ? Call (method ,
O )。
如果 result 不是对象 ,返回
result 。
抛出 TypeError 异常。
7.1.2 ToBoolean ( argument )
抽象操作 ToBoolean 接受参数 argument (一个ECMAScript
语言值 )并返回一个布尔值。它将 argument 转换为布尔类型的值。它在被调用时执行以下步骤:
如果 argument 是布尔值 ,返回
argument 。
如果 argument 是
undefined 、null 、+0 𝔽 、-0 𝔽 、NaN 、0 ℤ
或空字符串之一,返回 false 。
注意:此步骤在章节 B.3.6.1 中被替换。
返回 true 。
7.1.3 ToNumeric ( value )
抽象操作 ToNumeric 接受参数 value (一个ECMAScript
语言值 )并返回一个包含 数字或
BigInt 的正常完成 ,或一个throw 完成 。它返回转换为数字或
BigInt 的 value 。它在被调用时执行以下步骤:
设 primValue 为 ? ToPrimitive (value ,
number )。
如果 primValue 是
BigInt ,返回 primValue 。
返回 ? ToNumber (primValue )。
7.1.4 ToNumber ( argument )
抽象操作 ToNumber 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 数字的正常完成 或一个throw 完成 。它将
argument 转换为数字类型的值。它在被调用时执行以下步骤:
如果 argument 是数字 ,返回
argument 。
如果 argument 是符号或 BigInt,抛出 TypeError 异常。
如果 argument 是 undefined ,返回 NaN 。
如果 argument 是 null 或 false ,返回
+0 𝔽 。
如果 argument 是 true ,返回 1 𝔽 。
如果 argument 是字符串 ,返回
StringToNumber (argument )。
断言 :argument 是对象 。
设 primValue 为 ? ToPrimitive (argument ,
number )。
断言 :primValue 不是对象 。
返回 ? ToNumber (primValue )。
7.1.4.1 ToNumber 应用于字符串类型
抽象操作 StringToNumber 指定如何使用以下语法将字符串值转换为数字值。
语法
StringNumericLiteral
:::
StrWhiteSpace opt
StrWhiteSpace opt
StrNumericLiteral
StrWhiteSpace opt
StrWhiteSpace
:::
StrWhiteSpaceChar
StrWhiteSpace opt
StrWhiteSpaceChar
:::
WhiteSpace
LineTerminator
StrNumericLiteral
:::
StrDecimalLiteral
NonDecimalIntegerLiteral [~Sep]
StrDecimalLiteral
:::
StrUnsignedDecimalLiteral
+
StrUnsignedDecimalLiteral
-
StrUnsignedDecimalLiteral
StrUnsignedDecimalLiteral
:::
Infinity
DecimalDigits [~Sep]
.
DecimalDigits [~Sep] opt
ExponentPart [~Sep] opt
.
DecimalDigits [~Sep]
ExponentPart [~Sep] opt
DecimalDigits [~Sep]
ExponentPart [~Sep] opt
所有未在上面明确定义的语法符号都具有数字字面量词法语法中使用的定义(12.9.3 )
注意
7.1.4.1.1 StringToNumber ( str )
抽象操作 StringToNumber 接受参数 str (一个字符串)并返回一个数字。它在被调用时执行以下步骤:
设 literal 为 ParseText (str , StringNumericLiteral )。
如果 literal 是错误的列表 ,返回
NaN 。
返回 literal 的 StringNumericValue 。
7.1.4.1.2 运行时语义:StringNumericValue
语法导向操作
StringNumericValue 不接受参数并返回一个数字。
注意
它在以下产生式上分段定义:
StringNumericLiteral
:::
StrWhiteSpace
opt
返回 +0 𝔽 。
StringNumericLiteral
:::
StrWhiteSpace
opt
StrNumericLiteral
StrWhiteSpace
opt
返回 StrNumericLiteral 的
StringNumericValue 。
StrNumericLiteral
:::
NonDecimalIntegerLiteral
返回 𝔽 (NonDecimalIntegerLiteral
的 MV)。
StrDecimalLiteral
:::
-
StrUnsignedDecimalLiteral
设 a 为 StrUnsignedDecimalLiteral
的 StringNumericValue 。
如果 a 是 +0 𝔽 ,返回
-0 𝔽 。
返回 -a 。
StrUnsignedDecimalLiteral
:::
Infinity
返回 +∞ 𝔽 。
StrUnsignedDecimalLiteral
:::
DecimalDigits
.
DecimalDigits
opt
ExponentPart
opt
设 a 为第一个 DecimalDigits 的 MV。
如果第二个 DecimalDigits 存在,那么
设 b 为第二个 DecimalDigits 的 MV。
设 n 为第二个 DecimalDigits 中的代码点数。
否则,
设 b 为 0。
设 n 为 0。
如果 ExponentPart 存在,设 e 为
ExponentPart 的
MV。否则,设 e 为 0。
返回 RoundMVResult ((a +
(b × 10-n )) × 10e )。
StrUnsignedDecimalLiteral
:::
.
DecimalDigits
ExponentPart
opt
设 b 为 DecimalDigits 的 MV。
如果 ExponentPart 存在,设 e 为
ExponentPart 的
MV。否则,设 e 为 0。
设 n 为 DecimalDigits 中的代码点数。
返回 RoundMVResult (b ×
10e - n )。
StrUnsignedDecimalLiteral
:::
DecimalDigits
ExponentPart
opt
设 a 为 DecimalDigits 的 MV。
如果 ExponentPart 存在,设 e 为
ExponentPart 的
MV。否则,设 e 为 0。
返回 RoundMVResult (a ×
10e )。
7.1.4.1.3 RoundMVResult ( n )
抽象操作 RoundMVResult 接受参数 n (一个数学值 )并返回一个数字。它以实现定义 的方式将 n
转换为数字。对于此抽象操作的目的,如果数字不是零或其左侧有非零数字且其右侧有非零数字,则该数字是有效的。对于此抽象操作的目的,数学值 表示法的"表示的数学值"是数学值 的"十进制表示"的逆。它在被调用时执行以下步骤:
如果 n 的十进制表示有 20 或更少的有效数字,返回 𝔽 (n )。
设 option1 为将 n 的十进制表示中第 20 位后的每个有效数字替换为 0
数字的结果表示的数学值 。
设 option2 为将 n 的十进制表示中第 20 位后的每个有效数字替换为 0 数字,然后在第 20 位增加
1(根据需要进位)的结果表示的数学值 。
设 chosen 为 option1 或 option2 的实现定义 选择。
返回 𝔽 (chosen )。
7.1.5 ToIntegerOrInfinity ( argument )
抽象操作 ToIntegerOrInfinity 接受参数 argument (一个ECMAScript 语言值 )并返回一个包含 整数 、+∞ 或 -∞ 的正常完成 或一个throw 完成 。它将
argument 转换为表示其数字值的整数 (小数部分被截断),或者当该数字值是无限时转换为 +∞ 或 -∞。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 是 NaN 、+0 𝔽 或
-0 𝔽 之一,返回 0。
如果 number 是 +∞ 𝔽 ,返回 +∞。
如果 number 是 -∞ 𝔽 ,返回 -∞。
返回 truncate (ℝ (number ))。
注意
对于任何值
x ,
𝔽 (ToIntegerOrInfinity(
x )) 永远不会返回
-0 𝔽 。小数部分的截断在将
x 转换为
数学值 之后执行。
7.1.6 ToInt32 ( argument )
抽象操作 ToInt32 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 转换为从 𝔽 (-231 ) 到 𝔽 (231 - 1) 的闭区间 内的 232 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 不是有限的 或 number 是
+0 𝔽 或 -0 𝔽 ,返回
+0 𝔽 。
设 int 为 truncate (ℝ (number ))。
设 int32bit 为 int modulo 232 。
如果 int32bit ≥ 231 ,返回 𝔽 (int32bit - 232 );否则返回
𝔽 (int32bit )。
注意
根据 ToInt32 的上述定义:
ToInt32 抽象操作是幂等的:如果应用于它产生的结果,第二次应用不会改变该值。
对于所有值 x ,ToInt32(ToUint32 (x )) 与
ToInt32(x ) 是相同的值。(为了保持这个后续属性,+∞ 𝔽 和
-∞ 𝔽 被映射为 +0 𝔽 。)
ToInt32 将 -0 𝔽 映射为 +0 𝔽 。
7.1.7 ToUint32 ( argument )
抽象操作 ToUint32 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 转换为从 +0 𝔽 到 𝔽 (232 - 1) 的闭区间 内的
232 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 不是有限的 或 number 是
+0 𝔽 或 -0 𝔽 ,返回
+0 𝔽 。
设 int 为 truncate (ℝ (number ))。
设 int32bit 为 int modulo 232 。
返回 𝔽 (int32bit )。
注意
根据 ToUint32 的上述定义:
步骤 5 是 ToUint32 和 ToInt32
之间的唯一区别。
ToUint32 抽象操作是幂等的:如果应用于它产生的结果,第二次应用不会改变该值。
对于所有值 x ,ToUint32(ToInt32 (x )) 与
ToUint32(x ) 是相同的值。(为了保持这个后续属性,+∞ 𝔽 和
-∞ 𝔽 被映射为 +0 𝔽 。)
ToUint32 将 -0 𝔽 映射为
+0 𝔽 。
7.1.8 ToInt16 ( argument )
抽象操作 ToInt16 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 转换为从 𝔽 (-215 ) 到 𝔽 (215 - 1) 的闭区间 内的 216 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 不是有限的 或 number 是
+0 𝔽 或 -0 𝔽 ,返回
+0 𝔽 。
设 int 为 truncate (ℝ (number ))。
设 int16bit 为 int modulo 216 。
如果 int16bit ≥ 215 ,返回 𝔽 (int16bit - 216 );否则返回
𝔽 (int16bit )。
7.1.9 ToUint16 ( argument )
抽象操作 ToUint16 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 转换为从 +0 𝔽 到 𝔽 (216 - 1) 的闭区间 内的
216 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 不是有限的 或 number 是
+0 𝔽 或 -0 𝔽 ,返回
+0 𝔽 。
设 int 为 truncate (ℝ (number ))。
设 int16bit 为 int modulo 216 。
返回 𝔽 (int16bit )。
注意
根据 ToUint16 的上述定义:
在步骤 4 中将 232 替换为
216 是 ToUint32 和 ToUint16 之间的唯一区别。
ToUint16 将 -0 𝔽 映射为
+0 𝔽 。
7.1.10 ToInt8 ( argument )
抽象操作 ToInt8 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 转换为从 -128 𝔽 到
127 𝔽 的闭区间 内的 28 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 不是有限的 或 number 是
+0 𝔽 或 -0 𝔽 ,返回
+0 𝔽 。
设 int 为 truncate (ℝ (number ))。
设 int8bit 为 int modulo 28 。
如果 int8bit ≥ 27 ,返回 𝔽 (int8bit - 28 );否则返回 𝔽 (int8bit )。
7.1.11 ToUint8 ( argument )
抽象操作 ToUint8 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 转换为从 +0 𝔽 到
255 𝔽 的闭区间 内的 28 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 不是有限的 或 number 是
+0 𝔽 或 -0 𝔽 ,返回
+0 𝔽 。
设 int 为 truncate (ℝ (number ))。
设 int8bit 为 int modulo 28 。
返回 𝔽 (int8bit )。
7.1.12 ToUint8Clamp ( argument )
抽象操作 ToUint8Clamp 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 整数数字 的正常完成 或一个throw 完成 。它将
argument 限制并舍入为从 +0 𝔽 到
255 𝔽 的闭区间 内的 28 个整数数字 值之一。它在被调用时执行以下步骤:
设 number 为 ? ToNumber (argument )。
如果 number 是 NaN ,返回 +0 𝔽 。
设 mv 为 number 的扩展数学值 。
设 clamped 为将 mv 限制 在 0 和 255 之间的结果。
设 f 为 floor (clamped )。
如果 clamped < f + 0.5,返回 𝔽 (f )。
如果 clamped > f + 0.5,返回 𝔽 (f + 1)。
如果 f 是偶数,返回 𝔽 (f )。否则,返回 𝔽 (f + 1)。
注意
与大多数其他 ECMAScript 整数 转换操作不同,ToUint8Clamp
舍入而不是截断非整数值。它还使用"舍入到最近偶数"的平分策略,这与 Math.round 的"舍入到更大值"平分策略不同。
7.1.13 ToBigInt ( argument )
抽象操作 ToBigInt 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 BigInt
的正常完成 或一个throw 完成 。它将
argument 转换为 BigInt 值,或者如果需要从数字进行隐式转换则抛出异常。它在被调用时执行以下步骤:
设 prim 为 ? ToPrimitive (argument ,
number )。
返回 prim 在表 12 中对应的值。
表 12:BigInt 转换
参数类型
结果
Undefined
抛出 TypeError 异常。
Null
抛出 TypeError 异常。
Boolean
如果 prim 是 true 返回 1n,如果
prim 是 false 返回 0n。
BigInt
返回 prim 。
Number
抛出 TypeError 异常。
String
设 n 为 StringToBigInt (prim )。
如果 n 是 undefined ,抛出
SyntaxError 异常。
返回 n 。
Symbol
抛出 TypeError 异常。
7.1.14 StringToBigInt ( str )
抽象操作 StringToBigInt 接受参数 str (一个字符串)并返回一个 BigInt 或
undefined 。它在被调用时执行以下步骤:
设 literal 为 ParseText (str , StringIntegerLiteral )。
如果 literal 是错误的列表 ,返回
undefined 。
设 mv 为 literal 的 MV。
断言 :mv 是一个整数 。
返回 ℤ (mv )。
7.1.14.1 StringIntegerLiteral 语法
StringToBigInt 使用以下语法。
语法
StringIntegerLiteral
:::
StrWhiteSpace opt
StrWhiteSpace opt
StrIntegerLiteral
StrWhiteSpace opt
StrIntegerLiteral
:::
SignedInteger [~Sep]
NonDecimalIntegerLiteral [~Sep]
7.1.14.2 运行时语义:MV
7.1.15 ToBigInt64 ( argument )
抽象操作 ToBigInt64 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 BigInt
的正常完成 或一个throw 完成 。它将
argument 转换为从 ℤ (-263 ) 到 ℤ (263 - 1) 的闭区间 内的 264 个 BigInt
值之一。它在被调用时执行以下步骤:
设 n 为 ? ToBigInt (argument )。
设 int64bit 为 ℝ (n ) modulo 264 。
如果 int64bit ≥ 263 ,返回 ℤ (int64bit - 264 );否则返回 ℤ (int64bit )。
7.1.16 ToBigUint64 ( argument )
抽象操作 ToBigUint64 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 BigInt
的正常完成 或一个throw 完成 。它将
argument 转换为从 0 ℤ 到 ℤ (264 - 1) 的闭区间 内的 264 个 BigInt
值之一。它在被调用时执行以下步骤:
设 n 为 ? ToBigInt (argument )。
设 int64bit 为 ℝ (n ) modulo 264 。
返回 ℤ (int64bit )。
7.1.17 ToString ( argument )
抽象操作 ToString 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 字符串的正常完成 或一个throw 完成 。它将
argument 转换为字符串类型的值。它在被调用时执行以下步骤:
如果 argument 是字符串 ,返回
argument 。
如果 argument 是符号 ,抛出
TypeError 异常。
如果 argument 是 undefined ,返回 "undefined" 。
如果 argument 是 null ,返回 "null" 。
如果 argument 是 true ,返回 "true" 。
如果 argument 是 false ,返回 "false" 。
如果 argument 是数字 ,返回
Number::toString (argument ,
10)。
如果 argument 是
BigInt ,返回 BigInt::toString (argument ,
10)。
断言 :argument 是对象 。
设 primValue 为 ? ToPrimitive (argument ,
string )。
断言 :primValue 不是对象 。
返回 ? ToString (primValue )。
7.1.18 ToObject ( argument )
抽象操作 ToObject 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 对象的正常完成 或一个throw 完成 。它根据表
13 将 argument 转换为对象类型的值:
表 13:ToObject 转换
参数类型
结果
Undefined
抛出 TypeError 异常。
Null
抛出 TypeError 异常。
Boolean
返回一个新的布尔对象,其 [[BooleanData]] 内部槽设置为
argument 。有关布尔对象的描述,请参见 20.3 。
Number
返回一个新的数字对象,其 [[NumberData]] 内部槽设置为
argument 。有关数字对象的描述,请参见 21.1 。
String
返回一个新的字符串对象,其 [[StringData]] 内部槽设置为
argument 。有关字符串对象的描述,请参见 22.1 。
Symbol
返回一个新的符号对象,其 [[SymbolData]] 内部槽设置为
argument 。有关符号对象的描述,请参见 20.4 。
BigInt
返回一个新的 BigInt 对象,其 [[BigIntData]] 内部槽设置为
argument 。有关 BigInt 对象的描述,请参见 21.2 。
Object
返回 argument 。
7.1.19 ToPropertyKey ( argument )
抽象操作 ToPropertyKey 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 属性键 的正常完成 或一个throw 完成 。它将
argument 转换为可用作属性键 的值。它在被调用时执行以下步骤:
设 key 为 ? ToPrimitive (argument ,
string )。
如果 key 是符号 ,那么
返回 key 。
返回 ! ToString (key )。
7.1.20 ToLength ( argument )
抽象操作 ToLength 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 非负整数数字 的正常完成 或一个throw 完成 。它将
argument 限制并截断为适合用作类数组对象 长度的非负整数数字 。它在被调用时执行以下步骤:
设 len 为 ? ToIntegerOrInfinity (argument )。
如果 len ≤ 0,返回 +0 𝔽 。
返回 𝔽 (min (len ,
253 - 1))。
7.1.21 CanonicalNumericIndexString ( argument )
抽象操作 CanonicalNumericIndexString 接受参数 argument (一个字符串)并返回一个数字或
undefined 。如果 argument 是 "-0" 或完全匹配某个数字值
n 的 ToString (n ),它返回相应的数字值。否则,它返回
undefined 。它在被调用时执行以下步骤:
如果 argument 是 "-0" ,返回 -0 𝔽 。
设 n 为 ! ToNumber (argument )。
如果 ! ToString (n ) 是
argument ,返回 n 。
返回 undefined 。
规范数字字符串 是 CanonicalNumericIndexString 抽象操作不返回
undefined 的任何字符串。
7.1.22 ToIndex ( value )
抽象操作 ToIndex 接受参数 value (一个ECMAScript
语言值 )并返回一个包含 非负整数 的正常完成 或一个throw 完成 。它将
value 转换为整数 ,如果该整数 非负且对应于整数索引 则返回该整数。否则,它抛出异常。它在被调用时执行以下步骤:
设 integer 为 ? ToIntegerOrInfinity (value )。
如果 integer 不在从 0 到 253 - 1 的闭区间 内,抛出
RangeError 异常。
返回 integer 。
7.2 测试和比较操作
7.2.1 RequireObjectCoercible ( argument )
抽象操作 RequireObjectCoercible 接受参数 argument (一个ECMAScript 语言值 )并返回一个包含 ECMAScript 语言值 的正常完成 或一个throw 完成 。如果
argument 是不能使用 ToObject 转换为对象的值,它抛出错误。它由表 14 定义:
表 14:RequireObjectCoercible 结果
参数类型
结果
Undefined
抛出 TypeError 异常。
Null
抛出 TypeError 异常。
Boolean
返回 argument 。
Number
返回 argument 。
String
返回 argument 。
Symbol
返回 argument 。
BigInt
返回 argument 。
Object
返回 argument 。
7.2.2 IsArray ( argument )
抽象操作 IsArray 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 布尔值的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 argument 不是对象 ,返回 false 。
如果 argument 是数组异质对象 ,返回 true 。
如果 argument 是代理异质对象 ,那么
执行 ? ValidateNonRevokedProxy (argument )。
设 proxyTarget 为 argument .[[ProxyTarget]] 。
返回 ? IsArray (proxyTarget )。
返回 false 。
7.2.3 IsCallable ( argument )
抽象操作 IsCallable 接受参数 argument (一个ECMAScript
语言值 )并返回一个布尔值。它确定 argument 是否是具有 [[Call]] 内部方法的可调用函数。它在被调用时执行以下步骤:
如果 argument 不是对象 ,返回 false 。
如果 argument 有 [[Call]] 内部方法,返回
true 。
返回 false 。
7.2.4 IsConstructor ( argument )
抽象操作 IsConstructor 接受参数 argument (一个ECMAScript
语言值 )并返回一个布尔值。它确定 argument 是否是具有 [[Construct]] 内部方法的函数对象 。它在被调用时执行以下步骤:
如果 argument 不是对象 ,返回 false 。
如果 argument 有 [[Construct]] 内部方法,返回
true 。
返回 false 。
7.2.5 IsExtensible ( O )
抽象操作 IsExtensible 接受参数 O (一个对象)并返回一个包含 布尔值的正常完成 或一个throw 完成 。它用于确定是否可以向
O 添加其他属性。它在被调用时执行以下步骤:
返回 ? O .[[IsExtensible]] ()。
7.2.6 IsRegExp ( argument )
抽象操作 IsRegExp 接受参数 argument (一个ECMAScript
语言值 )并返回一个包含 布尔值的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 argument 不是对象 ,返回 false 。
设 matcher 为 ? Get (argument , %Symbol.match% )。
如果 matcher 不是 undefined ,返回 ToBoolean (matcher )。
如果 argument 有 [[RegExpMatcher]] 内部槽,返回
true 。
返回 false 。
7.2.7 静态语义:IsStringWellFormedUnicode ( string )
抽象操作 IsStringWellFormedUnicode 接受参数 string (一个字符串)并返回一个布尔值。它将 string 解释为
UTF-16 编码代码点的序列,如6.1.4 中所述,并确定它是否是一个格式正确的 UTF-16
序列。它在被调用时执行以下步骤:
设 len 为 string 的长度。
设 k 为 0。
重复,当 k < len 时,
设 cp 为 CodePointAt (string ,
k )。
如果 cp .[[IsUnpairedSurrogate]] 是
true ,返回 false 。
设 k 为 k + cp .[[CodeUnitCount]] 。
返回 true 。
7.2.8 SameType ( x , y )
抽象操作 SameType 接受参数 x (一个ECMAScript 语言值 )和
y (一个ECMAScript
语言值 )并返回一个布尔值。它确定两个参数是否为相同类型。它在被调用时执行以下步骤:
如果 x 是 undefined 且 y 是
undefined ,返回 true 。
如果 x 是 null 且 y 是 null ,返回
true 。
如果 x 是布尔值 且
y 是布尔值 ,返回
true 。
如果 x 是数字 且
y 是数字 ,返回
true 。
如果 x 是
BigInt 且 y 是 BigInt ,返回
true 。
如果 x 是符号 且
y 是符号 ,返回
true 。
如果 x 是字符串 且
y 是字符串 ,返回
true 。
如果 x 是对象 且 y 是对象 ,返回 true 。
返回 false 。
7.2.9 SameValue ( x , y )
抽象操作 SameValue 接受参数 x (一个ECMAScript 语言值 )和
y (一个ECMAScript
语言值 )并返回一个布尔值。它确定两个参数是否为相同值。它在被调用时执行以下步骤:
如果 SameType (x , y ) 是
false ,返回 false 。
如果 x 是数字 ,那么
返回 Number::sameValue (x ,
y )。
返回 SameValueNonNumber (x ,
y )。
注意
此算法与 IsStrictlyEqual 算法不同,它将所有
NaN 值视为等价,并区分 +0 𝔽 和
-0 𝔽 。
7.2.10 SameValueZero ( x , y )
抽象操作 SameValueZero 接受参数 x (一个ECMAScript 语言值 )和
y (一个ECMAScript
语言值 )并返回一个布尔值。它确定两个参数是否为相同值(忽略 +0 𝔽 和
-0 𝔽 之间的区别)。它在被调用时执行以下步骤:
如果 SameType (x , y ) 是
false ,返回 false 。
如果 x 是数字 ,那么
返回 Number::sameValueZero (x ,
y )。
返回 SameValueNonNumber (x ,
y )。
注意
SameValueZero 与 SameValue 的区别仅在于它将
+0 𝔽 和 -0 𝔽 视为等价。
7.2.11 SameValueNonNumber ( x , y )
抽象操作 SameValueNonNumber 接受参数 x (一个ECMAScript
语言值 ,但不是数字)和 y (一个ECMAScript
语言值 ,但不是数字)并返回一个布尔值。它在被调用时执行以下步骤:
断言 :SameType (x , y ) 是
true 。
如果 x 是 null 或 undefined ,返回
true 。
如果 x 是
BigInt ,那么
返回 BigInt::equal (x ,
y )。
如果 x 是字符串 ,那么
如果 x 和 y 有相同的长度且在相同位置有相同的代码单元,返回
true ;否则,返回 false 。
如果 x 是布尔值 ,那么
如果 x 和 y 都是 true 或都是
false ,返回 true ;否则,返回
false 。
注意:所有其他ECMAScript 语言值 按标识进行比较。
如果 x 是 y ,返回 true ;否则,返回
false 。
注意 1
为了说明目的,即使不必要,此算法中的某些情况也被单独处理。
注意 2
7.2.12 IsLessThan ( x , y , LeftFirst
)
抽象操作 IsLessThan 接受参数 x (一个ECMAScript
语言值 )、y (一个ECMAScript 语言值 )和
LeftFirst (一个布尔值)并返回一个包含 布尔值或
undefined 的正常完成 ,或一个throw 完成 。它为比较
x < y 提供语义,返回 true 、false 或
undefined (表示至少一个操作数是 NaN )。LeftFirst 标志用于控制对
x 和 y 执行可能具有可见副作用的操作的顺序。这是必要的,因为 ECMAScript 指定表达式的从左到右求值。如果
LeftFirst 是 true ,x 参数对应于出现在 y
参数对应表达式左侧的表达式。如果 LeftFirst 是 false ,则相反,必须在 x 之前对
y 执行操作。它在被调用时执行以下步骤:
如果 LeftFirst 是 true ,那么
设 px 为 ? ToPrimitive (x ,
number )。
设 py 为 ? ToPrimitive (y ,
number )。
否则,
注意:需要颠倒求值顺序以保持从左到右的求值。
设 py 为 ? ToPrimitive (y ,
number )。
设 px 为 ? ToPrimitive (x ,
number )。
如果 px 是字符串 且
py 是字符串 ,那么
设 lx 为 px 的长度。
设 ly 为 py 的长度。
对于每个整数 i ,满足 0 ≤ i <
min (lx , ly ),按升序执行
设 cx 为 px 中索引 i 处代码单元的数值。
设 cy 为 py 中索引 i 处代码单元的数值。
如果 cx < cy ,返回 true 。
如果 cx > cy ,返回 false 。
如果 lx < ly ,返回 true 。否则,返回
false 。
否则,
如果 px 是
BigInt 且 py 是字符串 ,那么
设 ny 为 StringToBigInt (py )。
如果 ny 是 undefined ,返回
undefined 。
返回 BigInt::lessThan (px ,
ny )。
如果 px 是字符串 且
py 是
BigInt ,那么
设 nx 为 StringToBigInt (px )。
如果 nx 是 undefined ,返回
undefined 。
返回 BigInt::lessThan (nx ,
py )。
注意:因为 px 和 py 是原始值,求值顺序不重要。
设 nx 为 ? ToNumeric (px )。
设 ny 为 ? ToNumeric (py )。
如果 SameType (nx ,
ny ) 是 true ,那么
如果 nx 是数字 ,那么
返回 Number::lessThan (nx ,
ny )。
否则,
断言 :nx 是
BigInt 。
返回 BigInt::lessThan (nx ,
ny )。
断言 :nx 是
BigInt 且 ny 是数字 ,或
nx 是数字 且
ny 是
BigInt 。
如果 nx 或 ny 是 NaN ,返回
undefined 。
如果 nx 是 -∞ 𝔽 或 ny 是
+∞ 𝔽 ,返回 true 。
如果 nx 是 +∞ 𝔽 或 ny 是
-∞ 𝔽 ,返回 false 。
如果 ℝ (nx ) < ℝ (ny ),返回
true ;否则返回 false 。
注意 1
步骤 3 与处理加法运算符 +(13.15.3 )的算法中的步骤
1.c 不同,它使用逻辑与操作而不是逻辑或操作。
注意 2
字符串的比较使用 UTF-16 代码单元值序列的简单字典序。没有尝试使用 Unicode 规范中定义的更复杂的、面向语义的字符或字符串相等性和整理顺序定义。因此,根据
Unicode 标准规范相等但不在相同规范化形式中的字符串值可能测试为不相等。还要注意,对于包含代理对 的字符串,按代码单元 的字典序与按代码点 的顺序不同。
7.2.13 IsLooselyEqual ( x , y )
抽象操作 IsLooselyEqual 接受参数 x (一个ECMAScript 语言值 )和
y (一个ECMAScript 语言值 )并返回一个包含 布尔值的正常完成 或一个throw 完成 。它为
== 运算符提供语义。它在被调用时执行以下步骤:
如果 SameType (x , y ) 是
true ,那么
返回 IsStrictlyEqual (x ,
y )。
如果 x 是 null 且 y 是
undefined ,返回 true 。
如果 x 是 undefined 且 y 是
null ,返回 true 。
注意:此步骤在B.3.6.2 节中被替换。
如果 x 是数字 且
y 是字符串 ,返回
! IsLooselyEqual (x ,
! ToNumber (y ))。
如果 x 是字符串 且
y 是数字 ,返回
! IsLooselyEqual (! ToNumber (x ), y )。
如果 x 是
BigInt 且 y 是字符串 ,那么
设 n 为 StringToBigInt (y )。
如果 n 是 undefined ,返回 false 。
返回 ! IsLooselyEqual (x ,
n )。
如果 x 是字符串 且
y 是
BigInt ,返回 ! IsLooselyEqual (y ,
x )。
如果 x 是布尔值 ,返回
! IsLooselyEqual (! ToNumber (x ), y )。
如果 y 是布尔值 ,返回
! IsLooselyEqual (x ,
! ToNumber (y ))。
如果 x 是字符串、数字、BigInt 或符号,且 y 是对象 ,返回 ! IsLooselyEqual (x ,
? ToPrimitive (y ))。
如果 x 是对象 且 y 是字符串、数字、BigInt 或符号,返回
! IsLooselyEqual (? ToPrimitive (x ), y )。
如果 x 是
BigInt 且 y 是数字 ,或如果
x 是数字 且
y 是
BigInt ,那么
如果 x 不是有限的 或 y 不是有限的 ,返回
false 。
如果 ℝ (x )
= ℝ (y ),返回 true ;否则返回
false 。
返回 false 。
7.2.14 IsStrictlyEqual ( x , y )
抽象操作 IsStrictlyEqual 接受参数 x (一个ECMAScript 语言值 )和
y (一个ECMAScript 语言值 )并返回一个布尔值。它为
=== 运算符提供语义。它在被调用时执行以下步骤:
如果 SameType (x , y ) 是
false ,返回 false 。
如果 x 是数字 ,那么
返回 Number::equal (x ,
y )。
返回 SameValueNonNumber (x ,
y )。
注意
此算法与 SameValue 算法在处理有符号零和 NaN 方面有所不同。
7.3 对象操作
7.3.1 MakeBasicObject ( internalSlotsList )
抽象操作 MakeBasicObject 接受参数 internalSlotsList (一个内部槽名称的列表 )并返回一个对象。它是所有算法创建的
ECMAScript 对象的源头,包括普通对象 和异质对象 。它提取了创建所有对象时使用的通用步骤,并集中了对象创建过程。它在被调用时执行以下步骤:
设 internalSlotsList 为 internalSlotsList 和 « [[PrivateElements]] » 的列表连接 。
设 obj 为一个新创建的对象,为 internalSlotsList 中的每个名称都有一个内部槽。
注意:如对象内部方法和内部槽 中所述,除非另有规定,每个这样的内部槽的初始值都是
undefined 。
设 obj .[[PrivateElements]] 为一个新的空列表 。
将 obj 的基本内部方法设置为10.1
中指定的默认普通对象 定义。
断言 :如果调用者不会覆盖
obj 的 [[GetPrototypeOf]] 和 [[SetPrototypeOf]] 基本内部方法,那么 internalSlotsList 包含
[[Prototype]] 。
断言 :如果调用者不会覆盖
obj 的所有 [[SetPrototypeOf]] 、[[IsExtensible]] 和 [[PreventExtensions]] 基本内部方法,那么 internalSlotsList 包含
[[Extensible]] 。
如果 internalSlotsList 包含 [[Extensible]] ,设
obj .[[Extensible]] 为 true 。
返回 obj 。
注意
在本规范中,异质对象 是在诸如 ArrayCreate 和 BoundFunctionCreate 等抽象操作 中创建的,首先调用
MakeBasicObject 来获得一个基本的基础对象,然后覆盖该对象的一些或所有内部方法。为了封装异质对象 的创建,对象的基本内部方法永远不会在这些操作之外被修改。
7.3.2 Get ( O , P )
抽象操作 Get 接受参数 O (一个对象)和 P (一个属性键 )并返回一个包含 一个ECMAScript 语言值 的正常完成 或一个throw
完成 。它用于检索对象的特定属性的值。它在被调用时执行以下步骤:
返回 ? O .[[Get]] (P , O )。
7.3.3 GetV ( V , P )
抽象操作 GetV 接受参数 V (一个ECMAScript 语言值 )和
P (一个属性键 )并返回一个包含 一个ECMAScript 语言值 的正常完成 或一个throw 完成 。它用于检索ECMAScript
语言值 的特定属性的值。如果该值不是对象,则使用适合该值类型的包装器对象执行属性查找。它在被调用时执行以下步骤:
设 O 为 ? ToObject (V )。
返回 ? O .[[Get]] (P , V )。
7.3.4 Set ( O , P , V ,
Throw )
抽象操作 Set 接受参数 O (一个对象)、P (一个属性键 )、V (一个ECMAScript 语言值 )和
Throw (一个布尔值)并返回一个包含
unused 的正常完成 或一个throw
完成 。它用于设置对象的特定属性的值。V 是该属性的新值。它在被调用时执行以下步骤:
设 success 为 ? O .[[Set]] (P , V , O )。
如果 success 是 false 且 Throw 是
true ,抛出 TypeError 异常。
返回 unused 。
7.3.5 CreateDataProperty ( O , P , V
)
抽象操作 CreateDataProperty 接受参数 O (一个对象)、P (一个属性键 )和 V (一个ECMAScript 语言值 )并返回一个包含 布尔值的正常完成 或一个throw
完成 。它用于创建对象的新自有属性。它在被调用时执行以下步骤:
设 newDesc 为 PropertyDescriptor { [[Value]] :
V , [[Writable]] : true , [[Enumerable]] : true , [[Configurable]] : true }。
返回 ? O .[[DefineOwnProperty]] (P ,
newDesc )。
注意
此抽象操作创建一个属性,其特性设置为与 ECMAScript 语言赋值运算符创建的属性相同的默认值。通常,该属性还不存在。如果它存在且不可配置,或者如果 O
不可扩展,[[DefineOwnProperty]] 将返回 false 。
7.3.6 CreateDataPropertyOrThrow ( O , P ,
V )
抽象操作 CreateDataPropertyOrThrow 接受参数 O (一个对象)、P (一个属性键 )和
V (一个ECMAScript 语言值 )并返回一个包含
unused 的正常完成 或一个throw
完成 。它用于创建对象的新自有属性。如果请求的属性更新无法执行,它抛出 TypeError
异常。它在被调用时执行以下步骤:
设 success 为 ? CreateDataProperty (O ,
P , V )。
如果 success 是 false ,抛出 TypeError 异常。
返回 unused 。
注意
此抽象操作创建一个属性,其特性设置为与 ECMAScript 语言赋值运算符创建的属性相同的默认值。通常,该属性还不存在。如果它存在且不可配置,或者如果 O
不可扩展,[[DefineOwnProperty]] 将返回 false ,导致此操作抛出
TypeError 异常。
7.3.7 CreateNonEnumerableDataPropertyOrThrow ( O ,
P , V )
抽象操作 CreateNonEnumerableDataPropertyOrThrow 接受参数 O (一个对象)、P (一个属性键 )和
V (一个ECMAScript 语言值 )并返回
unused 。它用于创建普通对象 的新的不可枚举自有属性。它在被调用时执行以下步骤:
断言 :O
是一个普通的、可扩展的、没有不可配置属性的对象。
设 newDesc 为 PropertyDescriptor { [[Value]] :
V , [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : true }。
执行 ! DefinePropertyOrThrow (O ,
P , newDesc )。
返回 unused 。
注意
此抽象操作创建一个属性,其特性设置为与 ECMAScript 语言赋值运算符创建的属性相同的默认值,但它不可枚举。通常,该属性还不存在。如果它存在,DefinePropertyOrThrow 保证正常完成。
7.3.8 DefinePropertyOrThrow ( O , P ,
desc )
抽象操作 DefinePropertyOrThrow 接受参数 O (一个对象)、P (一个属性键 )和 desc (一个属性描述符 )并返回一个包含
unused 的正常完成 或一个throw 完成 。它用于以一种方式调用对象的
[[DefineOwnProperty]] 内部方法,如果请求的属性更新无法执行,将抛出
TypeError 异常。它在被调用时执行以下步骤:
设 success 为 ? O .[[DefineOwnProperty]] (P , desc )。
如果 success 是 false ,抛出 TypeError 异常。
返回 unused 。
7.3.9 DeletePropertyOrThrow ( O , P )
抽象操作 DeletePropertyOrThrow 接受参数 O (一个对象)和 P (一个属性键 )并返回一个包含
unused 的正常完成 或一个throw
完成 。它用于删除对象的特定自有属性。如果属性不可配置,它抛出异常。它在被调用时执行以下步骤:
设 success 为 ? O .[[Delete]] (P )。
如果 success 是 false ,抛出 TypeError 异常。
返回 unused 。
7.3.10 GetMethod ( V , P )
抽象操作 GetMethod 接受参数 V (一个ECMAScript 语言值 )和
P (一个属性键 )并返回一个包含 一个函数对象 或
undefined 的正常完成 ,或一个throw 完成 。它用于获取ECMAScript
语言值 的特定属性的值,当该属性的值预期是一个函数时。它在被调用时执行以下步骤:
设 func 为 ? GetV (V , P )。
如果 func 是 undefined 或 null ,返回
undefined 。
如果 IsCallable (func ) 是
false ,抛出 TypeError 异常。
返回 func 。
7.3.11 HasProperty ( O , P )
抽象操作 HasProperty 接受参数 O (一个对象)和 P (一个属性键 )并返回一个包含 布尔值的正常完成 或一个throw
完成 。它用于确定对象是否具有指定属性键 的属性。该属性可能是自有的或继承的。它在被调用时执行以下步骤:
返回 ? O .[[HasProperty]] (P )。
7.3.12 HasOwnProperty ( O , P )
抽象操作 HasOwnProperty 接受参数 O (一个对象)和 P (一个属性键 )并返回一个包含 布尔值的正常完成 或一个throw
完成 。它用于确定对象是否具有指定属性键 的自有属性。它在被调用时执行以下步骤:
设 desc 为 ? O .[[GetOwnProperty]] (P )。
如果 desc 是 undefined ,返回 false 。
返回 true 。
7.3.13 Call ( F , V [ ,
argumentsList ] )
抽象操作 Call 接受参数 F (一个ECMAScript 语言值 )和
V (一个ECMAScript 语言值 )以及可选参数
argumentsList (一个ECMAScript 语言值 的列表 )并返回一个包含 一个ECMAScript 语言值 的正常完成 或一个throw 完成 。它用于调用函数对象 的 [[Call]] 内部方法。F 是函数对象 ,V 是作为 [[Call]] 的 this 值的ECMAScript
语言值 ,argumentsList 是传递给内部方法相应参数的值。如果 argumentsList
不存在,则使用一个新的空列表 作为其值。它在被调用时执行以下步骤:
如果 argumentsList 不存在,设 argumentsList 为一个新的空列表 。
如果 IsCallable (F ) 是
false ,抛出 TypeError 异常。
返回 ? F .[[Call]] (V , argumentsList )。
7.3.14 Construct ( F [ , argumentsList [ ,
newTarget ] ] )
抽象操作 Construct 接受参数 F (一个构造器 )以及可选参数 argumentsList (一个ECMAScript 语言值 的列表 )和
newTarget (一个构造器 )并返回一个包含 对象的正常完成 或一个throw 完成 。它用于调用函数对象 的 [[Construct]] 内部方法。argumentsList 和 newTarget
是要作为内部方法相应参数传递的值。如果 argumentsList 不存在,则使用一个新的空列表 作为其值。如果
newTarget 不存在,则使用 F 作为其值。它在被调用时执行以下步骤:
如果 newTarget 不存在,设 newTarget 为 F 。
如果 argumentsList 不存在,设 argumentsList 为一个新的空列表 。
返回 ? F .[[Construct]] (argumentsList ,
newTarget )。
注意
如果 newTarget 不存在,此操作等价于:new F(...argumentsList)
7.3.15 SetIntegrityLevel ( O , level )
抽象操作 SetIntegrityLevel 接受参数 O (一个对象)和 level (sealed 或
frozen )并返回一个包含 布尔值的正常完成 或一个throw
完成 。它用于固定对象自有属性的集合。它在被调用时执行以下步骤:
设 status 为 ? O .[[PreventExtensions]] ()。
如果 status 是 false ,返回 false 。
设 keys 为 ? O .[[OwnPropertyKeys]] ()。
如果 level 是 sealed ,那么
对于 keys 的每个元素 k ,执行
执行 ? DefinePropertyOrThrow (O ,
k , PropertyDescriptor { [[Configurable]] :
false })。
否则,
断言 :level 是
frozen 。
对于 keys 的每个元素 k ,执行
设 currentDesc 为 ? O .[[GetOwnProperty]] (k )。
如果 currentDesc 不是 undefined ,那么
如果 IsAccessorDescriptor (currentDesc )
是 true ,那么
设 desc 为 PropertyDescriptor { [[Configurable]] :
false }。
否则,
设 desc 为 PropertyDescriptor { [[Configurable]] :
false , [[Writable]] :
false }。
执行 ? DefinePropertyOrThrow (O ,
k , desc )。
返回 true 。
7.3.16 TestIntegrityLevel ( O , level )
抽象操作 TestIntegrityLevel 接受参数 O (一个对象)和 level (sealed 或
frozen )并返回一个包含 布尔值的正常完成 或一个throw
完成 。它用于确定对象自有属性的集合是否被固定。它在被调用时执行以下步骤:
设 extensible 为 ? IsExtensible (O )。
如果 extensible 是 true ,返回 false 。
注意:如果对象是可扩展的,则不检查其任何属性。
设 keys 为 ? O .[[OwnPropertyKeys]] ()。
对于 keys 的每个元素 k ,执行
设 currentDesc 为 ? O .[[GetOwnProperty]] (k )。
如果 currentDesc 不是 undefined ,那么
如果 currentDesc .[[Configurable]] 是
true ,返回 false 。
如果 level 是 frozen 且 IsDataDescriptor (currentDesc )
是 true ,那么
如果 currentDesc .[[Writable]]
是 true ,返回 false 。
返回 true 。
7.3.17 CreateArrayFromList ( elements )
抽象操作 CreateArrayFromList 接受参数 elements (一个ECMAScript 语言值 的列表 )并返回一个数组。它用于创建一个由
elements 提供元素的数组。它在被调用时执行以下步骤:
设 array 为 ! ArrayCreate (0)。
设 n 为 0。
对于 elements 的每个元素 e ,执行
执行 ! CreateDataPropertyOrThrow (array ,
! ToString (𝔽 (n )),
e )。
设 n 为 n + 1。
返回 array 。
7.3.18 LengthOfArrayLike ( obj )
抽象操作 LengthOfArrayLike 接受参数 obj (一个对象)并返回一个包含 非负整数 的正常完成 或一个throw 完成 。它返回类数组对象的
"length" 属性的值。它在被调用时执行以下步骤:
返回 ℝ (? ToLength (? Get (obj ,
"length" )))。
类数组对象 是此操作返回正常完成 的任何对象。
注意 1
通常,类数组对象还会有一些带有
整数索引 名称的属性。但是,这不是此定义的要求。
注意 2
数组和字符串对象是类数组对象的例子。
7.3.19 CreateListFromArrayLike ( obj [ ,
validElementTypes ] )
抽象操作 CreateListFromArrayLike 接受参数 obj (一个ECMAScript 语言值 )和可选参数
validElementTypes (all 或
property-key )并返回一个包含 ECMAScript 语言值 的列表 的正常完成 或一个throw
完成 。它用于创建一个列表 值,其元素由
obj 的索引属性提供。validElementTypes 指示允许作为元素的值的类型。它在被调用时执行以下步骤:
如果 validElementTypes 不存在,设 validElementTypes 为
all 。
如果 obj 不是对象 ,抛出 TypeError 异常。
设 len 为 ? LengthOfArrayLike (obj )。
设 list 为一个新的空列表 。
设 index 为 0。
重复,当 index < len 时,
设 indexName 为 ! ToString (𝔽 (index ))。
设 next 为 ? Get (obj ,
indexName )。
如果 validElementTypes 是 property-key 且
next 不是属性键 ,抛出 TypeError
异常。
将 next 追加到 list 。
设 index 为 index + 1。
返回 list 。
7.3.20 Invoke ( V , P [ ,
argumentsList ] )
抽象操作 Invoke 接受参数 V (一个ECMAScript 语言值 )和
P (一个属性键 )以及可选参数 argumentsList (一个ECMAScript 语言值 的列表 )并返回一个包含 一个ECMAScript 语言值 的正常完成 或一个throw 完成 。它用于调用ECMAScript 语言值 的方法属性。V
既作为属性的查找点,也作为调用的 this 值。argumentsList 是传递给方法的参数值列表。如果
argumentsList 不存在,则使用一个新的空列表 作为其值。它在被调用时执行以下步骤:
如果 argumentsList 不存在,设 argumentsList 为一个新的空列表 。
设 func 为 ? GetV (V , P )。
返回 ? Call (func , V ,
argumentsList )。
7.3.21 OrdinaryHasInstance ( C , O )
抽象操作 OrdinaryHasInstance 接受参数 C (一个ECMAScript 语言值 )和
O (一个ECMAScript 语言值 )并返回一个包含 布尔值的正常完成 或一个throw 完成 。它实现了确定
O 是否继承自 C 提供的实例对象继承路径的默认算法。它在被调用时执行以下步骤:
如果 IsCallable (C ) 是
false ,返回 false 。
如果 C 有 [[BoundTargetFunction]] 内部槽,那么
设 BC 为 C .[[BoundTargetFunction]] 。
返回 ? InstanceofOperator (O ,
BC )。
如果 O 不是对象 ,返回 false 。
设 P 为 ? Get (C ,
"prototype" )。
如果 P 不是对象 ,抛出 TypeError 异常。
重复,
设 O 为 ? O .[[GetPrototypeOf]] ()。
如果 O 是 null ,返回 false 。
如果 SameValue (P ,
O ) 是 true ,返回 true 。
7.3.22 SpeciesConstructor ( O ,
defaultConstructor )
抽象操作 SpeciesConstructor 接受参数 O (一个对象)和 defaultConstructor (一个构造器 )并返回一个包含 一个构造器 的正常完成 或一个throw 完成 。它用于检索应该用于创建从
O 派生的新对象的构造器 。defaultConstructor 是当从 O
开始无法找到构造器
%Symbol.species% 属性时要使用的构造器 。它在被调用时执行以下步骤:
设 C 为 ? Get (O ,
"constructor" )。
如果 C 是 undefined ,返回 defaultConstructor 。
如果 C 不是对象 ,抛出 TypeError 异常。
设 S 为 ? Get (C , %Symbol.species% )。
如果 S 是 undefined 或 null ,返回
defaultConstructor 。
如果 IsConstructor (S ) 是
true ,返回 S 。
抛出 TypeError 异常。
7.3.23 EnumerableOwnProperties ( O , kind )
抽象操作 EnumerableOwnProperties 接受参数 O (一个对象)和
kind (key 、value 或
key+value )并返回一个包含 ECMAScript 语言值 的列表 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 ownKeys 为 ? O .[[OwnPropertyKeys]] ()。
设 results 为一个新的空列表 。
对于 ownKeys 的每个元素 key ,执行
如果 key 是字符串 ,那么
设 desc 为 ? O .[[GetOwnProperty]] (key )。
如果 desc 不是 undefined 且
desc .[[Enumerable]] 是
true ,那么
如果 kind 是 key ,那么
将 key 追加到 results 。
否则,
设 value 为 ? Get (O ,
key )。
如果 kind 是 value ,那么
将 value 追加到 results 。
否则,
断言 :kind
是 key+value 。
设 entry 为 CreateArrayFromList («
key , value »)。
将 entry 追加到 results 。
返回 results 。
7.3.24 GetFunctionRealm ( obj )
抽象操作 GetFunctionRealm 接受参数 obj (一个函数对象 )并返回一个包含 一个Realm
Record 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 obj 有 [[Realm]] 内部槽,那么
返回 obj .[[Realm]] 。
如果 obj 是绑定函数异质对象 ,那么
设 boundTargetFunction 为 obj .[[BoundTargetFunction]] 。
返回 ? GetFunctionRealm (boundTargetFunction )。
如果 obj 是代理异质对象 ,那么
执行 ? ValidateNonRevokedProxy (obj )。
设 proxyTarget 为 obj .[[ProxyTarget]] 。
断言 :proxyTarget 是一个函数对象 。
返回 ? GetFunctionRealm (proxyTarget )。
返回当前 Realm Record 。
注意
只有当 obj 是一个没有 [[Realm]] 内部槽的非标准函数异质对象 时,才会执行步骤4 。
7.3.25 CopyDataProperties ( target , source ,
excludedItems )
抽象操作 CopyDataProperties 接受参数 target (一个对象)、source (一个ECMAScript 语言值 )和
excludedItems (一个属性键 的列表 )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 source 是 undefined 或 null ,返回
unused 。
设 from 为 ! ToObject (source )。
设 keys 为 ? from .[[OwnPropertyKeys]] ()。
对于 keys 的每个元素 nextKey ,执行
设 excluded 为 false 。
对于 excludedItems 的每个元素 e ,执行
如果 SameValue (e ,
nextKey ) 是 true ,那么
设 excluded 为 true 。
如果 excluded 是 false ,那么
设 desc 为 ? from .[[GetOwnProperty]] (nextKey )。
如果 desc 不是 undefined 且
desc .[[Enumerable]] 是
true ,那么
设 propValue 为 ? Get (from ,
nextKey )。
执行 ! CreateDataPropertyOrThrow (target ,
nextKey , propValue )。
返回 unused 。
注意
这里传入的目标总是一个新创建的对象,在抛出错误的情况下不能直接访问。
7.3.26 PrivateElementFind ( O , P )
抽象操作 PrivateElementFind 接受参数 O (一个对象)和 P (一个私有名称 )并返回一个PrivateElement 或
empty 。它在被调用时执行以下步骤:
如果 O .[[PrivateElements]] 包含一个PrivateElement
pe ,其中 pe .[[Key]] 是 P ,那么
返回 pe 。
返回 empty 。
7.3.27 PrivateFieldAdd ( O , P ,
value )
抽象操作 PrivateFieldAdd 接受参数 O (一个对象)、P (一个私有名称 )和
value (一个ECMAScript 语言值 )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果宿主 是 Web 浏览器,那么
执行 ? HostEnsureCanAddPrivateElement (O )。
设 entry 为 PrivateElementFind (O ,
P )。
如果 entry 不是 empty ,抛出 TypeError 异常。
将 PrivateElement {
[[Key]] : P , [[Kind]] :
field , [[Value]] :
value } 追加到 O .[[PrivateElements]] 。
返回 unused 。
7.3.28 PrivateMethodOrAccessorAdd ( O , method
)
抽象操作 PrivateMethodOrAccessorAdd 接受参数 O (一个对象)和 method (一个PrivateElement )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
断言 :method .[[Kind]] 是 method 或
accessor 。
如果宿主 是 Web 浏览器,那么
执行 ? HostEnsureCanAddPrivateElement (O )。
设 entry 为 PrivateElementFind (O ,
method .[[Key]] )。
如果 entry 不是 empty ,抛出 TypeError 异常。
将 method 追加到 O .[[PrivateElements]] 。
返回 unused 。
注意
私有方法和访问器的值在实例之间共享。此操作不会创建方法或访问器的新副本。
7.3.29 HostEnsureCanAddPrivateElement ( O )
宿主定义的 抽象操作
HostEnsureCanAddPrivateElement 接受参数 O (一个对象)并返回一个包含
unused 的正常完成 或一个throw 完成 。它允许宿主环境 阻止向特定的宿主定义的 异质对象 添加私有元素。
HostEnsureCanAddPrivateElement 的实现必须符合以下要求:
HostEnsureCanAddPrivateElement 的默认实现是返回 NormalCompletion (unused )。
此抽象操作仅由作为 Web 浏览器的 ECMAScript 宿主 调用。
7.3.30 PrivateGet ( O , P )
抽象操作 PrivateGet 接受参数 O (一个对象)和 P (一个私有名称 )并返回一个包含 一个ECMAScript 语言值 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 entry 为 PrivateElementFind (O ,
P )。
如果 entry 是 empty ,抛出 TypeError 异常。
如果 entry .[[Kind]] 是 field 或
method ,那么
返回 entry .[[Value]] 。
断言 :entry .[[Kind]] 是 accessor 。
如果 entry .[[Get]] 是 undefined ,抛出
TypeError 异常。
设 getter 为 entry .[[Get]] 。
返回 ? Call (getter , O )。
7.3.31 PrivateSet ( O , P , value )
抽象操作 PrivateSet 接受参数 O (一个对象)、P (一个私有名称 )和
value (一个ECMAScript 语言值 )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 entry 为 PrivateElementFind (O ,
P )。
如果 entry 是 empty ,抛出 TypeError 异常。
如果 entry .[[Kind]] 是 field ,那么
设 entry .[[Value]] 为 value 。
否则如果 entry .[[Kind]] 是
method ,那么
抛出 TypeError 异常。
否则,
断言 :entry .[[Kind]] 是 accessor 。
如果 entry .[[Set]] 是
undefined ,抛出 TypeError 异常。
设 setter 为 entry .[[Set]] 。
执行 ? Call (setter , O ,
« value »)。
返回 unused 。
7.3.32 DefineField ( receiver , fieldRecord )
抽象操作 DefineField 接受参数 receiver (一个对象)和 fieldRecord (一个ClassFieldDefinition
Record )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 fieldName 为 fieldRecord .[[Name]] 。
设 initializer 为 fieldRecord .[[Initializer]] 。
如果 initializer 不是 empty ,那么
设 initValue 为 ? Call (initializer ,
receiver )。
否则,
设 initValue 为 undefined 。
如果 fieldName 是私有名称 ,那么
执行 ? PrivateFieldAdd (receiver ,
fieldName , initValue )。
否则,
断言 :fieldName 是一个属性键 。
执行 ? CreateDataPropertyOrThrow (receiver ,
fieldName , initValue )。
返回 unused 。
7.3.33 InitializeInstanceElements ( O ,
constructor )
抽象操作 InitializeInstanceElements 接受参数 O (一个对象)和 constructor (一个 ECMAScript
函数对象 )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 methods 为 constructor .[[PrivateMethods]] 的值。
对于 methods 的每个PrivateElement
method ,执行
执行 ? PrivateMethodOrAccessorAdd (O ,
method )。
设 fields 为 constructor .[[Fields]] 的值。
对于 fields 的每个元素 fieldRecord ,执行
执行 ? DefineField (O ,
fieldRecord )。
返回 unused 。
7.3.34 AddValueToKeyedGroup ( groups , key ,
value )
抽象操作 AddValueToKeyedGroup 接受参数 groups (一个记录 的列表 ,具有字段 [[Key]] (一个ECMAScript 语言值 )和 [[Elements]] (一个ECMAScript
语言值 的列表 ))、key (一个ECMAScript 语言值 )和
value (一个ECMAScript 语言值 )并返回
unused 。它在被调用时执行以下步骤:
对于 groups 的每个记录 {
[[Key]] , [[Elements]] }
g ,执行
如果 SameValue (g .[[Key]] , key ) 是 true ,那么
断言 :groups
中恰好有一个元素满足此条件。
将 value 追加到 g .[[Elements]] 。
返回 unused 。
设 group 为记录 {
[[Key]] : key , [[Elements]] :
« value » }。
将 group 追加到 groups 。
返回 unused 。
7.3.35 GroupBy ( items , callback ,
keyCoercion )
抽象操作 GroupBy 接受参数 items (一个ECMAScript
语言值 )、callback (一个ECMAScript 语言值 )和
keyCoercion (property 或
collection )并返回一个包含 记录 的列表 的正常完成 (具有字段 [[Key]] (一个ECMAScript 语言值 )和 [[Elements]] (一个ECMAScript
语言值 的列表 ))或一个throw 完成 。它在被调用时执行以下步骤:
执行 ? RequireObjectCoercible (items )。
如果 IsCallable (callback ) 是
false ,抛出 TypeError 异常。
设 groups 为一个新的空列表 。
设 iteratorRecord 为 ? GetIterator (items ,
sync )。
设 k 为 0。
重复,
如果 k ≥ 253 - 1,那么
设 error 为 ThrowCompletion (新创建的
TypeError 对象)。
返回 ? IteratorClose (iteratorRecord ,
error )。
设 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,那么
返回 groups 。
设 value 为 next 。
设 key 为 Completion (Call (callback ,
undefined , « value , 𝔽 (k ) »))。
IfAbruptCloseIterator (key ,
iteratorRecord )。
如果 keyCoercion 是 property ,那么
设 key 为 Completion (ToPropertyKey (key ))。
IfAbruptCloseIterator (key ,
iteratorRecord )。
否则,
断言 :keyCoercion 是
collection 。
设 key 为 CanonicalizeKeyedCollectionKey (key )。
执行 AddValueToKeyedGroup (groups ,
key , value )。
设 k 为 k + 1。
7.3.36 SetterThatIgnoresPrototypeProperties ( thisValue ,
home , p , v )
抽象操作 SetterThatIgnoresPrototypeProperties 接受参数 thisValue (一个ECMAScript
语言值 )、home (一个对象)、p (一个属性键 )和 v (一个ECMAScript 语言值 )并返回一个包含
unused 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 thisValue 不是对象 ,那么
抛出 TypeError 异常。
如果 SameValue (thisValue ,
home ) 是 true ,那么
注意:这里抛出异常模拟了在严格模式代码 中对 home
对象上不可写数据属性 的赋值。
抛出 TypeError 异常。
设 desc 为 ? thisValue .[[GetOwnProperty]] (p )。
如果 desc 是 undefined ,那么
执行 ? CreateDataPropertyOrThrow (thisValue ,
p , v )。
否则,
执行 ? Set (thisValue ,
p , v , true )。
返回 unused 。
7.4 迭代器对象上的操作
参见通用迭代接口(27.1 )。
7.4.1 迭代器记录
迭代器记录 是一个记录 值,用于封装一个迭代器 或异步迭代器 以及其 next 方法。
迭代器记录具有表 15 中列出的字段。
表 15:迭代器记录 字段
7.4.2 GetIteratorDirect ( obj )
抽象操作 GetIteratorDirect 接受参数 obj (一个对象)并返回一个包含 一个迭代器记录 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 nextMethod 为 ? Get (obj ,
"next" )。
设 iteratorRecord 为迭代器记录 { [[Iterator]] : obj , [[NextMethod]] : nextMethod , [[Done]] : false }。
返回 iteratorRecord 。
7.4.3 GetIteratorFromMethod ( obj , method )
抽象操作 GetIteratorFromMethod 接受参数 obj (一个ECMAScript 语言值 )和
method (一个函数对象 )并返回一个包含 一个迭代器记录 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 iterator 为 ? Call (method , obj )。
如果 iterator 不是对象 ,抛出 TypeError 异常。
返回 ? GetIteratorDirect (iterator )。
7.4.4 GetIterator ( obj , kind )
抽象操作 GetIterator 接受参数 obj (一个ECMAScript 语言值 )和
kind (sync 或 async )并返回一个包含 一个迭代器记录 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 kind 是 async ,那么
设 method 为 ? GetMethod (obj , %Symbol.asyncIterator% )。
如果 method 是 undefined ,那么
设 syncMethod 为 ? GetMethod (obj ,
%Symbol.iterator% )。
如果 syncMethod 是 undefined ,抛出
TypeError 异常。
设 syncIteratorRecord 为 ? GetIteratorFromMethod (obj ,
syncMethod )。
返回 CreateAsyncFromSyncIterator (syncIteratorRecord )。
否则,
设 method 为 ? GetMethod (obj , %Symbol.iterator% )。
如果 method 是 undefined ,抛出 TypeError 异常。
返回 ? GetIteratorFromMethod (obj ,
method )。
7.4.5 GetIteratorFlattenable ( obj ,
primitiveHandling )
抽象操作 GetIteratorFlattenable 接受参数 obj (一个ECMAScript 语言值 )和
primitiveHandling (iterate-string-primitives 或
reject-primitives )并返回一个包含 一个迭代器记录 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 obj 不是对象 ,那么
如果 primitiveHandling 是 reject-primitives ,抛出
TypeError 异常。
断言 :primitiveHandling 是
iterate-string-primitives 。
如果 obj 不是字符串 ,抛出
TypeError 异常。
设 method 为 ? GetMethod (obj , %Symbol.iterator% )。
如果 method 是 undefined ,那么
设 iterator 为 obj 。
否则,
设 iterator 为 ? Call (method ,
obj )。
如果 iterator 不是对象 ,抛出 TypeError 异常。
返回 ? GetIteratorDirect (iterator )。
7.4.6 IteratorNext ( iteratorRecord [ , value
] )
抽象操作 IteratorNext 接受参数 iteratorRecord (一个迭代器记录 )和可选参数
value (一个ECMAScript 语言值 )并返回一个包含 一个对象的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
如果 value 不存在,那么
设 result 为 Completion (Call (iteratorRecord .[[NextMethod]] , iteratorRecord .[[Iterator]] ))。
否则,
设 result 为 Completion (Call (iteratorRecord .[[NextMethod]] , iteratorRecord .[[Iterator]] , « value »))。
如果 result 是throw
完成 ,那么
设 iteratorRecord .[[Done]] 为
true 。
返回 ? result 。
设 result 为 ! result 。
如果 result 不是对象 ,那么
设 iteratorRecord .[[Done]] 为
true 。
抛出 TypeError 异常。
返回 result 。
7.4.7 IteratorComplete ( iteratorResult )
抽象操作 IteratorComplete 接受参数 iteratorResult (一个对象)并返回一个包含 一个布尔值的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
返回 ToBoolean (? Get (iteratorResult ,
"done" ))。
7.4.8 IteratorValue ( iteratorResult )
抽象操作 IteratorValue 接受参数 iteratorResult (一个对象)并返回一个包含 一个ECMAScript 语言值 的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
返回 ? Get (iteratorResult ,
"value" )。
7.4.9 IteratorStep ( iteratorRecord )
抽象操作 IteratorStep 接受参数 iteratorRecord (一个迭代器记录 )并返回一个包含 一个对象或
done 的正常完成 ,或一个throw 完成 。它通过调用
iteratorRecord .[[NextMethod]] 从
iteratorRecord .[[Iterator]] 请求下一个值,并返回
done (表示迭代器 已到达末尾)或IteratorResult
对象 (如果下一个值可用)。它在被调用时执行以下步骤:
设 result 为 ? IteratorNext (iteratorRecord )。
设 done 为 Completion (IteratorComplete (result ))。
如果 done 是throw
完成 ,那么
设 iteratorRecord .[[Done]] 为
true 。
返回 ? done 。
设 done 为 ! done 。
如果 done 是 true ,那么
设 iteratorRecord .[[Done]] 为
true 。
返回 done 。
返回 result 。
7.4.10 IteratorStepValue ( iteratorRecord )
抽象操作 IteratorStepValue 接受参数 iteratorRecord (一个迭代器记录 )并返回一个包含 一个ECMAScript 语言值 或
done 的正常完成 ,或一个throw 完成 。它通过调用
iteratorRecord .[[NextMethod]] 从
iteratorRecord .[[Iterator]] 请求下一个值,并返回
done (表示迭代器 已到达末尾)或来自IteratorResult
对象 的值(如果下一个值可用)。它在被调用时执行以下步骤:
设 result 为 ? IteratorStep (iteratorRecord )。
如果 result 是 done ,那么
返回 done 。
设 value 为 Completion (IteratorValue (result ))。
如果 value 是throw
完成 ,那么
设 iteratorRecord .[[Done]] 为
true 。
返回 ? value 。
7.4.11 IteratorClose ( iteratorRecord ,
completion )
抽象操作 IteratorClose 接受参数 iteratorRecord (一个迭代器记录 )和
completion (一个完成记录 )并返回一个完成记录 。它用于通知迭代器 应该执行它在到达完成状态时通常要执行的任何操作。它在被调用时执行以下步骤:
断言 :iteratorRecord .[[Iterator]] 是一个对象 。
设 iterator 为 iteratorRecord .[[Iterator]] 。
设 innerResult 为 Completion (GetMethod (iterator ,
"return" ))。
如果 innerResult 是正常完成 ,那么
设 return 为 innerResult .[[Value]] 。
如果 return 是 undefined ,返回
? completion 。
设 innerResult 为 Completion (Call (return ,
iterator ))。
如果 completion 是throw
完成 ,返回 ? completion 。
如果 innerResult 是throw
完成 ,返回 ? innerResult 。
如果 innerResult .[[Value]] 不是对象 ,抛出 TypeError 异常。
返回 ? completion 。
7.4.12 IfAbruptCloseIterator ( value ,
iteratorRecord )
IfAbruptCloseIterator 是使用迭代器记录 的算法步骤序列的简写。形式为以下的算法步骤:
IfAbruptCloseIterator (value ,
iteratorRecord )。
与以下含义相同:
断言 :value 是一个完成记录 。
如果 value 是异常完成 ,返回
? IteratorClose (iteratorRecord ,
value )。
否则,设 value 为 ! value 。
7.4.13 AsyncIteratorClose ( iteratorRecord ,
completion )
抽象操作 AsyncIteratorClose 接受参数 iteratorRecord (一个迭代器记录 )和
completion (一个完成记录 )并返回一个完成记录 。它用于通知异步迭代器 应该执行它在到达完成状态时通常要执行的任何操作。它在被调用时执行以下步骤:
断言 :iteratorRecord .[[Iterator]] 是一个对象 。
设 iterator 为 iteratorRecord .[[Iterator]] 。
设 innerResult 为 Completion (GetMethod (iterator ,
"return" ))。
如果 innerResult 是正常完成 ,那么
设 return 为 innerResult .[[Value]] 。
如果 return 是 undefined ,返回
? completion 。
设 innerResult 为 Completion (Call (return ,
iterator ))。
如果 innerResult 是正常完成 ,设
innerResult 为 Completion (Await (innerResult .[[Value]] ))。
如果 completion 是throw
完成 ,返回 ? completion 。
如果 innerResult 是throw
完成 ,返回 ? innerResult 。
如果 innerResult .[[Value]] 不是对象 ,抛出 TypeError 异常。
返回 ? completion 。
7.4.14 CreateIteratorResultObject ( value ,
done )
抽象操作 CreateIteratorResultObject 接受参数 value (一个ECMAScript 语言值 )和
done (一个布尔值)并返回一个符合IteratorResult
接口 的对象。它创建一个符合IteratorResult
接口 的对象。它在被调用时执行以下步骤:
设 obj 为 OrdinaryObjectCreate (%Object.prototype% )。
执行 ! CreateDataPropertyOrThrow (obj ,
"value" , value )。
执行 ! CreateDataPropertyOrThrow (obj ,
"done" , done )。
返回 obj 。
7.4.15 CreateListIteratorRecord ( list )
抽象操作 CreateListIteratorRecord 接受参数 list (一个包含ECMAScript 语言值 的列表 )并返回一个迭代器记录 。它创建一个迭代器记录 ,其 [[NextMethod]] 返回 list 的连续元素。它在被调用时执行以下步骤:
设 closure 为一个新的抽象闭包 ,它没有参数,捕获
list ,并在被调用时执行以下步骤:
对于 list 的每个元素 E ,执行
执行 ? GeneratorYield (CreateIteratorResultObject (E ,
false ))。
返回 NormalCompletion (undefined )。
设 iterator 为 CreateIteratorFromClosure (closure ,
empty , %Iterator.prototype% )。
返回迭代器记录 { [[Iterator]] : iterator , [[NextMethod]] : %GeneratorPrototype.next%, [[Done]] : false }。
注意
列表迭代器对象 永远不会直接暴露给 ECMAScript 代码。
7.4.16 IteratorToList ( iteratorRecord )
抽象操作 IteratorToList 接受参数 iteratorRecord (一个迭代器记录 )并返回一个包含 一个列表 (包含ECMAScript 语言值 )的正常完成 或一个throw 完成 。它在被调用时执行以下步骤:
设 values 为一个新的空列表 。
重复,
设 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,那么
返回 values 。
将 next 追加到 values 。
8 语法定向操作
除了本节中定义的操作外,专用的语法定向操作 在本规范中各处都有定义。
8.1 运行时语义:Evaluation
语法定向操作
Evaluation 不接受参数并返回一个完成记录 。
注意
此操作的定义分布在本规范的"ECMAScript 语言"章节中。每个定义都出现在相关产生式的定义出现之后。
8.2 作用域分析
8.2.1 静态语义:BoundNames
语法定向操作
BoundNames 不接受参数并返回一个字符串的列表 。
注意
"*default*" 在本规范中用作模块的默认导出在没有其他名称时的合成名称。模块的 [[Environment]] 中会创建一个具有该名称的条目并保存相应的值,通过为模块调用 ResolveExport ( exportName [ ,
resolveSet ] ) 来解析名为 "default"
的导出将返回一个 ResolvedBinding 记录 ,其 [[BindingName]] 是 "*default*" ,然后在模块的 [[Environment]] 中解析为上述值。这样做只是为了便于规范,使匿名默认导出可以像任何其他导出一样解析。这个
"*default*" 字符串永远不会暴露给 ECMAScript 代码或模块链接算法。
它在以下产生式上分段定义:
BindingIdentifier
:
Identifier
返回一个列表 ,其唯一元素是 Identifier 的StringValue 。
BindingIdentifier
:
yield
返回 « "yield" »。
BindingIdentifier
:
await
返回 « "await" »。
LexicalDeclaration
:
LetOrConst
BindingList
;
返回 BindingList
的BoundNames 。
BindingList
:
BindingList
,
LexicalBinding
设 names1 为 BindingList 的BoundNames 。
设 names2 为 LexicalBinding 的BoundNames 。
返回 names1 和 names2 的列表连接 。
LexicalBinding
:
BindingIdentifier
Initializer opt
返回 BindingIdentifier 的BoundNames 。
LexicalBinding
:
BindingPattern
Initializer
返回 BindingPattern
的BoundNames 。
VariableDeclarationList
:
VariableDeclarationList
,
VariableDeclaration
设 names1 为 VariableDeclarationList
的BoundNames 。
设 names2 为 VariableDeclaration 的BoundNames 。
返回 names1 和 names2 的列表连接 。
VariableDeclaration
:
BindingIdentifier
Initializer opt
返回 BindingIdentifier 的BoundNames 。
VariableDeclaration
:
BindingPattern
Initializer
返回 BindingPattern
的BoundNames 。
ObjectBindingPattern
:
{
}
返回一个新的空列表 。
ObjectBindingPattern
:
{
BindingPropertyList
,
BindingRestProperty
}
设 names1 为 BindingPropertyList 的BoundNames 。
设 names2 为 BindingRestProperty 的BoundNames 。
返回 names1 和 names2 的列表连接 。
ArrayBindingPattern
:
[
Elision opt
]
返回一个新的空列表 。
ArrayBindingPattern
:
[
Elision opt
BindingRestElement
]
返回 BindingRestElement 的BoundNames 。
ArrayBindingPattern
:
[
BindingElementList
,
Elision opt
]
返回 BindingElementList 的BoundNames 。
ArrayBindingPattern
:
[
BindingElementList
,
Elision opt
BindingRestElement
]
设 names1 为 BindingElementList 的BoundNames 。
设 names2 为 BindingRestElement 的BoundNames 。
返回 names1 和 names2 的列表连接 。
BindingPropertyList
:
BindingPropertyList
,
BindingProperty
设 names1 为 BindingPropertyList 的BoundNames 。
设 names2 为 BindingProperty 的BoundNames 。
返回 names1 和 names2 的列表连接 。
BindingElementList
:
BindingElementList
,
BindingElisionElement
设 names1 为 BindingElementList 的BoundNames 。
设 names2 为 BindingElisionElement 的BoundNames 。
返回 names1 和 names2 的列表连接 。
BindingElisionElement
:
Elision opt
BindingElement
返回 BindingElement
的BoundNames 。
BindingProperty
:
PropertyName
:
BindingElement
返回 BindingElement
的BoundNames 。
SingleNameBinding
:
BindingIdentifier
Initializer opt
返回 BindingIdentifier 的BoundNames 。
BindingElement
:
BindingPattern
Initializer opt
返回 BindingPattern
的BoundNames 。
ForDeclaration
:
LetOrConst
ForBinding
返回 ForBinding 的BoundNames 。
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
返回 BindingIdentifier 的BoundNames 。
FunctionDeclaration
:
function
(
FormalParameters
)
{
FunctionBody
}
返回 « "*default*" »。
FormalParameters
:
[empty]
返回一个新的空列表 。
FormalParameters
:
FormalParameterList
,
FunctionRestParameter
设 names1 为 FormalParameterList 的BoundNames 。
设 names2 为 FunctionRestParameter 的BoundNames 。
返回 names1 和 names2 的列表连接 。
FormalParameterList
:
FormalParameterList
,
FormalParameter
设 names1 为 FormalParameterList 的BoundNames 。
设 names2 为 FormalParameter 的BoundNames 。
返回 names1 和 names2 的列表连接 。
ArrowParameters
:
CoverParenthesizedExpressionAndArrowParameterList
设 formals 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ArrowFormalParameters 。
返回 formals 的BoundNames 。
GeneratorDeclaration
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
返回 BindingIdentifier 的BoundNames 。
GeneratorDeclaration
:
function
*
(
FormalParameters
)
{
GeneratorBody
}
返回 « "*default*" »。
AsyncGeneratorDeclaration
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
返回 BindingIdentifier 的BoundNames 。
AsyncGeneratorDeclaration
:
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
返回 « "*default*" »。
ClassDeclaration
:
class
BindingIdentifier
ClassTail
返回 BindingIdentifier 的BoundNames 。
ClassDeclaration
:
class
ClassTail
返回 « "*default*" »。
AsyncFunctionDeclaration
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 BindingIdentifier 的BoundNames 。
AsyncFunctionDeclaration
:
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 « "*default*" »。
CoverCallExpressionAndAsyncArrowHead
:
MemberExpression
Arguments
设 head 为被 CoverCallExpressionAndAsyncArrowHead
覆盖 的 AsyncArrowHead 。
返回 head 的BoundNames 。
ImportDeclaration
:
import
ImportClause
FromClause
WithClause opt
;
返回 ImportClause
的BoundNames 。
ImportDeclaration
:
import
ModuleSpecifier
WithClause opt
;
返回一个新的空列表 。
ImportClause
:
ImportedDefaultBinding
,
NameSpaceImport
设 names1 为 ImportedDefaultBinding
的BoundNames 。
设 names2 为 NameSpaceImport 的BoundNames 。
返回 names1 和 names2 的列表连接 。
ImportClause
:
ImportedDefaultBinding
,
NamedImports
设 names1 为 ImportedDefaultBinding
的BoundNames 。
设 names2 为 NamedImports 的BoundNames 。
返回 names1 和 names2 的列表连接 。
NamedImports
:
{
}
返回一个新的空列表 。
ImportsList
:
ImportsList
,
ImportSpecifier
设 names1 为 ImportsList 的BoundNames 。
设 names2 为 ImportSpecifier 的BoundNames 。
返回 names1 和 names2 的列表连接 。
ImportSpecifier
:
ModuleExportName
as
ImportedBinding
返回 ImportedBinding
的BoundNames 。
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
export
NamedExports
;
返回一个新的空列表 。
ExportDeclaration
:
export
VariableStatement
返回 VariableStatement 的BoundNames 。
ExportDeclaration
:
export
Declaration
返回 Declaration
的BoundNames 。
ExportDeclaration
:
export
default
HoistableDeclaration
设 declarationNames 为 HoistableDeclaration 的BoundNames 。
如果 declarationNames 不包含元素 "*default*" ,则将
"*default*" 追加到 declarationNames 。
返回 declarationNames 。
ExportDeclaration
:
export
default
ClassDeclaration
设 declarationNames 为 ClassDeclaration 的BoundNames 。
如果 declarationNames 不包含元素 "*default*" ,则将
"*default*" 追加到 declarationNames 。
返回 declarationNames 。
ExportDeclaration
:
export
default
AssignmentExpression
;
返回 « "*default*" »。
8.2.2 静态语义:DeclarationPart
语法定向操作
DeclarationPart 不接受参数并返回一个解析节点 。它在以下产生式上分段定义:
HoistableDeclaration
: FunctionDeclaration
返回 FunctionDeclaration 。
HoistableDeclaration
: GeneratorDeclaration
返回 GeneratorDeclaration 。
HoistableDeclaration
: AsyncFunctionDeclaration
返回 AsyncFunctionDeclaration 。
HoistableDeclaration
: AsyncGeneratorDeclaration
返回 AsyncGeneratorDeclaration 。
Declaration : ClassDeclaration
返回 ClassDeclaration 。
Declaration : LexicalDeclaration
返回 LexicalDeclaration 。
8.2.3 静态语义:IsConstantDeclaration
语法定向操作
IsConstantDeclaration 不接受参数并返回一个布尔值。它在以下产生式上分段定义:
LexicalDeclaration
:
LetOrConst
BindingList
;
返回 LetOrConst 的IsConstantDeclaration 。
LetOrConst : let
返回 false 。
LetOrConst : const
返回 true 。
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
function
(
FormalParameters
)
{
FunctionBody
}
GeneratorDeclaration
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
function
*
(
FormalParameters
)
{
GeneratorBody
}
AsyncGeneratorDeclaration
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncFunctionDeclaration
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 false 。
ClassDeclaration :
class
BindingIdentifier
ClassTail
class
ClassTail
返回 false 。
ExportDeclaration
:
export
ExportFromClause
FromClause
;
export
NamedExports
;
export
default
AssignmentExpression
;
返回 false 。
注意
没有必要将 export default AssignmentExpression
视为常量声明,因为没有语法允许对用于引用模块默认对象的内部绑定名称进行赋值。
8.2.4 静态语义:词法声明的名称 (LexicallyDeclaredNames)
语法导向操作
LexicallyDeclaredNames 不接受参数,并返回一个字符串列表 。它根据以下产生式分段定义:
Block :
{
}
返回一个新的空列表 。
StatementList :
StatementList
StatementListItem
令 names1 为 StatementList 的 LexicallyDeclaredNames 。
令 names2 为 StatementListItem 的 LexicallyDeclaredNames 。
返回 names1 和 names2 的列表连接 。
StatementListItem
: Statement
如果 Statement 是
Statement :
LabelledStatement
,则返回 LabelledStatement 的 LexicallyDeclaredNames 。
返回一个新的空列表 。
StatementListItem
: Declaration
返回 Declaration 的
BoundNames 。
CaseBlock :
{
}
返回一个新的空列表 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,令
names1 为第一个 CaseClauses 的 LexicallyDeclaredNames 。
否则,令 names1 为一个新的空列表 。
令 names2 为 DefaultClause 的 LexicallyDeclaredNames 。
如果第二个 CaseClauses 存在,令
names3 为第二个 CaseClauses 的 LexicallyDeclaredNames 。
否则,令 names3 为一个新的空列表 。
返回 names1 、names2 和 names3 的列表连接 。
CaseClauses :
CaseClauses
CaseClause
令 names1 为 CaseClauses 的 LexicallyDeclaredNames 。
令 names2 为 CaseClause 的 LexicallyDeclaredNames 。
返回 names1 和 names2 的列表连接 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,则返回 StatementList
的 LexicallyDeclaredNames 。
返回一个新的空列表 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,则返回 StatementList
的 LexicallyDeclaredNames 。
返回一个新的空列表 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 的
LexicallyDeclaredNames 。
LabelledItem : Statement
返回一个新的空列表 。
LabelledItem : FunctionDeclaration
返回 FunctionDeclaration 的 BoundNames 。
FunctionStatementList
: [空]
返回一个新的空列表 。
FunctionStatementList
: StatementList
返回 StatementList 的
TopLevelLexicallyDeclaredNames 。
ClassStaticBlockStatementList
: [空]
返回一个新的空列表 。
ClassStaticBlockStatementList
: StatementList
返回 StatementList 的
TopLevelLexicallyDeclaredNames 。
ConciseBody : ExpressionBody
返回一个新的空列表 。
AsyncConciseBody :
ExpressionBody
返回一个新的空列表 。
Script : [空]
返回一个新的空列表 。
ScriptBody : StatementList
返回 StatementList 的
TopLevelLexicallyDeclaredNames 。
注 1
在 Script 的顶层,函数声明被视为类似 var
声明,而不是类似词法声明。
注 2
Module 的
LexicallyDeclaredNames 包含其所有导入绑定的名称。
ModuleItemList :
ModuleItemList
ModuleItem
令 names1 为 ModuleItemList 的 LexicallyDeclaredNames 。
令 names2 为 ModuleItem 的 LexicallyDeclaredNames 。
返回 names1 和 names2 的列表连接 。
ModuleItem : ImportDeclaration
返回 ImportDeclaration 的 BoundNames 。
ModuleItem : ExportDeclaration
如果 ExportDeclaration 是
export VariableStatement ,则返回一个新的
空列表 。
返回 ExportDeclaration 的 BoundNames 。
ModuleItem : StatementListItem
返回 StatementListItem 的 LexicallyDeclaredNames 。
注 3
在 Module
的顶层,函数声明被视为类似词法声明,而不是类似 var 声明。
8.2.5 静态语义:词法作用域声明 (LexicallyScopedDeclarations)
语法导向操作
LexicallyScopedDeclarations 不接受参数,并返回一个解析节点 的列表 。它根据以下产生式分段定义:
StatementList :
StatementList
StatementListItem
令 declarations1 为 StatementList 的 LexicallyScopedDeclarations 。
令 declarations2 为 StatementListItem 的 LexicallyScopedDeclarations 。
返回 declarations1 和 declarations2 的列表连接 。
StatementListItem
: Statement
如果 Statement 是
Statement :
LabelledStatement
,则返回 LabelledStatement 的 LexicallyScopedDeclarations 。
返回一个新的空列表 。
StatementListItem
: Declaration
返回一个列表 ,其唯一元素是 Declaration 的 DeclarationPart 。
CaseBlock :
{
}
返回一个新的空列表 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,令
declarations1 为第一个 CaseClauses 的 LexicallyScopedDeclarations 。
否则,令 declarations1 为一个新的空列表 。
令 declarations2 为 DefaultClause 的 LexicallyScopedDeclarations 。
如果第二个 CaseClauses 存在,令
declarations3 为第二个 CaseClauses 的 LexicallyScopedDeclarations 。
否则,令 declarations3 为一个新的空列表 。
返回 declarations1 、declarations2 和 declarations3
的列表连接 。
CaseClauses :
CaseClauses
CaseClause
令 declarations1 为 CaseClauses 的 LexicallyScopedDeclarations 。
令 declarations2 为 CaseClause 的 LexicallyScopedDeclarations 。
返回 declarations1 和 declarations2 的列表连接 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,则返回 StatementList
的 LexicallyScopedDeclarations 。
返回一个新的空列表 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,则返回 StatementList
的 LexicallyScopedDeclarations 。
返回一个新的空列表 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 的
LexicallyScopedDeclarations 。
LabelledItem : Statement
返回一个新的空列表 。
LabelledItem : FunctionDeclaration
返回 « FunctionDeclaration »。
FunctionStatementList
: [空]
返回一个新的空列表 。
FunctionStatementList
: StatementList
返回 StatementList 的
TopLevelLexicallyScopedDeclarations 。
ClassStaticBlockStatementList
: [空]
返回一个新的空列表 。
ClassStaticBlockStatementList
: StatementList
返回 StatementList 的
TopLevelLexicallyScopedDeclarations 。
ConciseBody : ExpressionBody
返回一个新的空列表 。
AsyncConciseBody :
ExpressionBody
返回一个新的空列表 。
Script : [空]
返回一个新的空列表 。
ScriptBody : StatementList
返回 StatementList 的
TopLevelLexicallyScopedDeclarations 。
Module : [空]
返回一个新的空列表 。
ModuleItemList :
ModuleItemList
ModuleItem
令 declarations1 为 ModuleItemList 的 LexicallyScopedDeclarations 。
令 declarations2 为 ModuleItem 的 LexicallyScopedDeclarations 。
返回 declarations1 和 declarations2 的列表连接 。
ModuleItem : ImportDeclaration
返回一个新的空列表 。
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
export
NamedExports
;
export
VariableStatement
返回一个新的空列表 。
ExportDeclaration
:
export
Declaration
返回一个列表 ,其唯一元素是 Declaration 的 DeclarationPart 。
ExportDeclaration
:
export
default
HoistableDeclaration
返回一个列表 ,其唯一元素是 HoistableDeclaration 的 DeclarationPart 。
ExportDeclaration
:
export
default
ClassDeclaration
返回一个列表 ,其唯一元素是 ClassDeclaration 。
ExportDeclaration
:
export
default
AssignmentExpression
;
返回一个列表 ,其唯一元素是这个
ExportDeclaration 。
8.2.6 静态语义:VarDeclaredNames
语法导向操作
VarDeclaredNames 不接受参数,并返回一个字符串列表 。它根据以下产生式分段定义:
Statement :
EmptyStatement
ExpressionStatement
ContinueStatement
BreakStatement
ReturnStatement
ThrowStatement
DebuggerStatement
返回一个新的空列表 。
Block :
{
}
返回一个新的空列表 。
StatementList :
StatementList
StatementListItem
令 names1 为 StatementList 的 VarDeclaredNames 。
令 names2 为 StatementListItem 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
StatementListItem
: Declaration
返回一个新的空列表 。
VariableStatement
:
var
VariableDeclarationList
;
返回 VariableDeclarationList 的
BoundNames 。
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 names1 为第一个 Statement 的 VarDeclaredNames 。
令 names2 为第二个 Statement 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
IfStatement :
if
(
Expression
)
Statement
返回 Statement 的 VarDeclaredNames 。
DoWhileStatement :
do
Statement
while
(
Expression
)
;
返回 Statement 的 VarDeclaredNames 。
WhileStatement :
while
(
Expression
)
Statement
返回 Statement 的 VarDeclaredNames 。
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
返回 Statement 的 VarDeclaredNames 。
ForStatement :
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
令 names1 为 VariableDeclarationList 的
BoundNames 。
令 names2 为 Statement 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
ForStatement :
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
返回 Statement 的 VarDeclaredNames 。
ForInOfStatement :
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
返回 Statement 的 VarDeclaredNames 。
ForInOfStatement :
for
(
var
ForBinding
in
Expression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
令 names1 为 ForBinding 的 BoundNames 。
令 names2 为 Statement 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
注
WithStatement :
with
(
Expression
)
Statement
返回 Statement 的 VarDeclaredNames 。
SwitchStatement :
switch
(
Expression
)
CaseBlock
返回 CaseBlock 的 VarDeclaredNames 。
CaseBlock :
{
}
返回一个新的空列表 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,令
names1 为第一个 CaseClauses 的 VarDeclaredNames 。
否则,令 names1 为一个新的空列表 。
令 names2 为 DefaultClause 的 VarDeclaredNames 。
如果第二个 CaseClauses 存在,令
names3 为第二个 CaseClauses 的 VarDeclaredNames 。
否则,令 names3 为一个新的空列表 。
返回 names1 、names2 和 names3 的列表连接 。
CaseClauses :
CaseClauses
CaseClause
令 names1 为 CaseClauses 的 VarDeclaredNames 。
令 names2 为 CaseClause 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,则返回 StatementList
的 VarDeclaredNames 。
返回一个新的空列表 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,则返回 StatementList
的 VarDeclaredNames 。
返回一个新的空列表 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 的
VarDeclaredNames 。
LabelledItem : FunctionDeclaration
返回一个新的空列表 。
TryStatement :
try
Block
Catch
令 names1 为 Block 的
VarDeclaredNames 。
令 names2 为 Catch 的
VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
TryStatement :
try
Block
Finally
令 names1 为 Block 的
VarDeclaredNames 。
令 names2 为 Finally 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
TryStatement :
try
Block
Catch
Finally
令 names1 为 Block 的
VarDeclaredNames 。
令 names2 为 Catch 的
VarDeclaredNames 。
令 names3 为 Finally 的 VarDeclaredNames 。
返回 names1 、names2 和 names3 的列表连接 。
Catch :
catch
(
CatchParameter
)
Block
返回 Block 的 VarDeclaredNames 。
FunctionStatementList
: [空]
返回一个新的空列表 。
FunctionStatementList
: StatementList
返回 StatementList 的
TopLevelVarDeclaredNames 。
ClassStaticBlockStatementList
: [空]
返回一个新的空列表 。
ClassStaticBlockStatementList
: StatementList
返回 StatementList 的
TopLevelVarDeclaredNames 。
ConciseBody : ExpressionBody
返回一个新的空列表 。
AsyncConciseBody :
ExpressionBody
返回一个新的空列表 。
Script : [空]
返回一个新的空列表 。
ScriptBody : StatementList
返回 StatementList 的
TopLevelVarDeclaredNames 。
ModuleItemList :
ModuleItemList
ModuleItem
令 names1 为 ModuleItemList 的 VarDeclaredNames 。
令 names2 为 ModuleItem 的 VarDeclaredNames 。
返回 names1 和 names2 的列表连接 。
ModuleItem : ImportDeclaration
返回一个新的空列表 。
ModuleItem : ExportDeclaration
如果 ExportDeclaration 是
export VariableStatement ,则返回 ExportDeclaration 的
BoundNames 。
返回一个新的空列表 。
8.2.7 静态语义:VarScopedDeclarations
语法导向操作
VarScopedDeclarations 不接受参数,返回一个包含
解析节点 的
列表 。它针对以下产生式分段定义:
Statement :
EmptyStatement
ExpressionStatement
ContinueStatement
BreakStatement
ReturnStatement
ThrowStatement
DebuggerStatement
返回一个新的空列表 。
Block :
{
}
返回一个新的空列表 。
StatementList :
StatementList
StatementListItem
令 declarations1 为 StatementList 的 VarScopedDeclarations 。
令 declarations2 为 StatementListItem 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
StatementListItem
: Declaration
返回一个新的空列表 。
VariableDeclarationList
: VariableDeclaration
返回 « VariableDeclaration »。
VariableDeclarationList
:
VariableDeclarationList
,
VariableDeclaration
令 declarations1 为 VariableDeclarationList 的
VarScopedDeclarations 。
返回 declarations1 和 « VariableDeclaration » 的
列表连接 。
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 declarations1 为第一个 Statement 的 VarScopedDeclarations 。
令 declarations2 为第二个 Statement 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
IfStatement :
if
(
Expression
)
Statement
返回 Statement 的 VarScopedDeclarations 。
DoWhileStatement :
do
Statement
while
(
Expression
)
;
返回 Statement 的 VarScopedDeclarations 。
WhileStatement :
while
(
Expression
)
Statement
返回 Statement 的 VarScopedDeclarations 。
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
返回 Statement 的 VarScopedDeclarations 。
ForStatement :
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
令 declarations1 为 VariableDeclarationList 的
VarScopedDeclarations 。
令 declarations2 为 Statement 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
ForStatement :
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
返回 Statement 的 VarScopedDeclarations 。
ForInOfStatement :
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
返回 Statement 的 VarScopedDeclarations 。
ForInOfStatement :
for
(
var
ForBinding
in
Expression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
令 declarations1 为 « ForBinding »。
令 declarations2 为 Statement 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
注
WithStatement :
with
(
Expression
)
Statement
返回 Statement 的 VarScopedDeclarations 。
SwitchStatement :
switch
(
Expression
)
CaseBlock
返回 CaseBlock 的 VarScopedDeclarations 。
CaseBlock :
{
}
返回一个新的空列表 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,令
declarations1 为第一个 CaseClauses 的 VarScopedDeclarations 。
否则,令 declarations1 为一个新的空列表 。
令 declarations2 为 DefaultClause 的 VarScopedDeclarations 。
如果第二个 CaseClauses 存在,令
declarations3 为第二个 CaseClauses 的 VarScopedDeclarations 。
否则,令 declarations3 为一个新的空列表 。
返回 declarations1 、declarations2 和 declarations3 的
列表连接 。
CaseClauses :
CaseClauses
CaseClause
令 declarations1 为 CaseClauses 的 VarScopedDeclarations 。
令 declarations2 为 CaseClause 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,返回 StatementList 的
VarScopedDeclarations 。
返回一个新的空列表 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,返回 StatementList 的
VarScopedDeclarations 。
返回一个新的空列表 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 的
VarScopedDeclarations 。
LabelledItem : FunctionDeclaration
返回一个新的空列表 。
TryStatement :
try
Block
Catch
令 declarations1 为 Block 的 VarScopedDeclarations 。
令 declarations2 为 Catch 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
TryStatement :
try
Block
Finally
令 declarations1 为 Block 的 VarScopedDeclarations 。
令 declarations2 为 Finally 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
TryStatement :
try
Block
Catch
Finally
令 declarations1 为 Block 的 VarScopedDeclarations 。
令 declarations2 为 Catch 的 VarScopedDeclarations 。
令 declarations3 为 Finally 的 VarScopedDeclarations 。
返回 declarations1 、declarations2 和 declarations3 的
列表连接 。
Catch :
catch
(
CatchParameter
)
Block
返回 Block 的 VarScopedDeclarations 。
FunctionStatementList
: [空]
返回一个新的空 列表 。
FunctionStatementList
: StatementList
返回 StatementList 的
TopLevelVarScopedDeclarations 。
ClassStaticBlockStatementList
: [空]
返回一个新的空 列表 。
ClassStaticBlockStatementList
: StatementList
返回 StatementList 的
TopLevelVarScopedDeclarations 。
ConciseBody : ExpressionBody
返回一个新的空 列表 。
AsyncConciseBody :
ExpressionBody
返回一个新的空 列表 。
Script : [空]
返回一个新的空 列表 。
ScriptBody : StatementList
返回 StatementList 的
TopLevelVarScopedDeclarations 。
Module : [空]
返回一个新的空 列表 。
ModuleItemList :
ModuleItemList
ModuleItem
令 declarations1 为 ModuleItemList 的 VarScopedDeclarations 。
令 declarations2 为 ModuleItem 的 VarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
ModuleItem : ImportDeclaration
返回一个新的空 列表 。
ModuleItem : ExportDeclaration
如果 ExportDeclaration 是
export VariableStatement ,返回 VariableStatement 的
VarScopedDeclarations 。
返回一个新的空 列表 。
8.2.8 静态语义:TopLevelLexicallyDeclaredNames
语法导向操作
TopLevelLexicallyDeclaredNames 不接受参数并返回一个字符串的 列表 。它在以下产生式上分段定义:
StatementList :
StatementList
StatementListItem
令 names1 为 StatementList 的 TopLevelLexicallyDeclaredNames 。
令 names2 为 StatementListItem 的 TopLevelLexicallyDeclaredNames 。
返回 names1 和 names2 的 列表连接 。
StatementListItem
: Statement
返回一个新的空 列表 。
StatementListItem
: Declaration
如果 Declaration 是
Declaration
: HoistableDeclaration
,那么
返回一个新的空 列表 。
返回 Declaration 的
BoundNames 。
注意
在函数或脚本的顶层,函数声明被当作 var 声明处理,而不是词法声明。
8.2.9 静态语义:TopLevelLexicallyScopedDeclarations
语法导向操作
TopLevelLexicallyScopedDeclarations 不接受参数并返回一个 解析节点 的 列表 。它在以下产生式上分段定义:
StatementList :
StatementList
StatementListItem
令 declarations1 为 StatementList 的 TopLevelLexicallyScopedDeclarations 。
令 declarations2 为 StatementListItem 的 TopLevelLexicallyScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
StatementListItem
: Statement
返回一个新的空 列表 。
StatementListItem
: Declaration
如果 Declaration 是
Declaration
: HoistableDeclaration
,那么
返回一个新的空 列表 。
返回 « Declaration »。
8.2.10 静态语义:TopLevelVarDeclaredNames
语法导向操作
TopLevelVarDeclaredNames 不接受参数并返回一个字符串的 列表 。它在以下产生式上分段定义:
StatementList :
StatementList
StatementListItem
令 names1 为 StatementList 的 TopLevelVarDeclaredNames 。
令 names2 为 StatementListItem 的 TopLevelVarDeclaredNames 。
返回 names1 和 names2 的 列表连接 。
StatementListItem
: Declaration
如果 Declaration 是
Declaration
: HoistableDeclaration
,那么
返回 HoistableDeclaration 的
BoundNames 。
返回一个新的空 列表 。
StatementListItem
: Statement
如果 Statement 是
Statement :
LabelledStatement
,返回 Statement 的 TopLevelVarDeclaredNames 。
返回 Statement 的 VarDeclaredNames 。
注意
在函数或脚本的顶层,内部函数声明被当作 var 声明处理。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 的
TopLevelVarDeclaredNames 。
LabelledItem : Statement
如果 Statement 是
Statement :
LabelledStatement
,返回 Statement 的 TopLevelVarDeclaredNames 。
返回 Statement 的 VarDeclaredNames 。
LabelledItem : FunctionDeclaration
返回 FunctionDeclaration 的 BoundNames 。
8.2.11 静态语义:TopLevelVarScopedDeclarations
语法导向操作
TopLevelVarScopedDeclarations 不接受参数并返回一个 解析节点 的 列表 。它在以下产生式上分段定义:
StatementList :
StatementList
StatementListItem
令 declarations1 为 StatementList 的 TopLevelVarScopedDeclarations 。
令 declarations2 为 StatementListItem 的 TopLevelVarScopedDeclarations 。
返回 declarations1 和 declarations2 的 列表连接 。
StatementListItem
: Statement
如果 Statement 是
Statement :
LabelledStatement
,返回 Statement 的 TopLevelVarScopedDeclarations 。
返回 Statement 的 VarScopedDeclarations 。
StatementListItem
: Declaration
如果 Declaration 是
Declaration
: HoistableDeclaration
,那么
令 declaration 为 HoistableDeclaration 的
DeclarationPart 。
返回 « declaration »。
返回一个新的空 列表 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 的
TopLevelVarScopedDeclarations 。
LabelledItem : Statement
如果 Statement 是
Statement :
LabelledStatement
,返回 Statement 的 TopLevelVarScopedDeclarations 。
返回 Statement 的 VarScopedDeclarations 。
LabelledItem : FunctionDeclaration
返回 « FunctionDeclaration »。
8.3 标签
8.3.1 静态语义:ContainsDuplicateLabels
语法导向操作
ContainsDuplicateLabels 接受参数 labelSet (一个字符串的 列表 )并返回一个布尔值。它在以下产生式上分段定义:
Statement :
VariableStatement
EmptyStatement
ExpressionStatement
ContinueStatement
BreakStatement
ReturnStatement
ThrowStatement
DebuggerStatement
Block :
{
}
StatementListItem
:
Declaration
返回 false 。
StatementList :
StatementList
StatementListItem
令 hasDuplicates 为以参数 labelSet 调用 StatementList 的 ContainsDuplicateLabels 。
如果 hasDuplicates 是 true ,返回 true 。
返回以参数 labelSet 调用 StatementListItem 的 ContainsDuplicateLabels 。
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 hasDuplicate 为以参数 labelSet 调用第一个 Statement 的 ContainsDuplicateLabels 。
如果 hasDuplicate 是 true ,返回 true 。
返回以参数 labelSet 调用第二个 Statement 的 ContainsDuplicateLabels 。
IfStatement :
if
(
Expression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsDuplicateLabels 。
DoWhileStatement :
do
Statement
while
(
Expression
)
;
返回以参数 labelSet 调用 Statement 的 ContainsDuplicateLabels 。
WhileStatement :
while
(
Expression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsDuplicateLabels 。
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsDuplicateLabels 。
ForInOfStatement :
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
var
ForBinding
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsDuplicateLabels 。
注意
WithStatement :
with
(
Expression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsDuplicateLabels 。
SwitchStatement :
switch
(
Expression
)
CaseBlock
返回以参数 labelSet 调用 CaseBlock 的 ContainsDuplicateLabels 。
CaseBlock :
{
}
返回 false 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,那么
如果以参数 labelSet 调用第一个 CaseClauses 的 ContainsDuplicateLabels
是 true ,返回 true 。
如果以参数 labelSet 调用 DefaultClause 的 ContainsDuplicateLabels
是 true ,返回 true 。
如果第二个 CaseClauses
不存在,返回 false 。
返回以参数 labelSet 调用第二个 CaseClauses 的 ContainsDuplicateLabels 。
CaseClauses :
CaseClauses
CaseClause
令 hasDuplicates 为以参数 labelSet 调用 CaseClauses 的 ContainsDuplicateLabels 。
如果 hasDuplicates 是 true ,返回 true 。
返回以参数 labelSet 调用 CaseClause 的 ContainsDuplicateLabels 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,返回以参数 labelSet 调用 StatementList 的 ContainsDuplicateLabels 。
返回 false 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,返回以参数 labelSet 调用 StatementList 的 ContainsDuplicateLabels 。
返回 false 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
令 label 为 LabelIdentifier 的 StringValue 。
如果 labelSet 包含 label ,返回 true 。
令 newLabelSet 为 labelSet 和 « label » 的 列表连接 。
返回以参数 newLabelSet 调用 LabelledItem 的 ContainsDuplicateLabels 。
LabelledItem : FunctionDeclaration
返回 false 。
TryStatement :
try
Block
Catch
令 hasDuplicates 为以参数 labelSet 调用 Block 的 ContainsDuplicateLabels 。
如果 hasDuplicates 是 true ,返回 true 。
返回以参数 labelSet 调用 Catch 的 ContainsDuplicateLabels 。
TryStatement :
try
Block
Finally
令 hasDuplicates 为以参数 labelSet 调用 Block 的 ContainsDuplicateLabels 。
如果 hasDuplicates 是 true ,返回 true 。
返回以参数 labelSet 调用 Finally 的 ContainsDuplicateLabels 。
TryStatement :
try
Block
Catch
Finally
如果以参数 labelSet 调用 Block 的 ContainsDuplicateLabels
是 true ,返回 true 。
如果以参数 labelSet 调用 Catch 的 ContainsDuplicateLabels
是 true ,返回 true 。
返回以参数 labelSet 调用 Finally 的 ContainsDuplicateLabels 。
Catch :
catch
(
CatchParameter
)
Block
返回以参数 labelSet 调用 Block 的 ContainsDuplicateLabels 。
FunctionStatementList
: [空]
返回 false 。
ClassStaticBlockStatementList
: [空]
返回 false 。
ModuleItemList :
ModuleItemList
ModuleItem
令 hasDuplicates 为以参数 labelSet 调用 ModuleItemList 的 ContainsDuplicateLabels 。
如果 hasDuplicates 是 true ,返回 true 。
返回以参数 labelSet 调用 ModuleItem 的 ContainsDuplicateLabels 。
ModuleItem :
ImportDeclaration
ExportDeclaration
返回 false 。
8.3.2 静态语义:ContainsUndefinedBreakTarget
语法导向操作
ContainsUndefinedBreakTarget 接受参数 labelSet
(一个字符串的 列表 )并返回一个布尔值。它在以下产生式上分段定义:
Statement :
VariableStatement
EmptyStatement
ExpressionStatement
ContinueStatement
ReturnStatement
ThrowStatement
DebuggerStatement
Block :
{
}
StatementListItem
:
Declaration
返回 false 。
StatementList :
StatementList
StatementListItem
令 hasUndefinedLabels 为以参数 labelSet 调用 StatementList 的 ContainsUndefinedBreakTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 labelSet 调用 StatementListItem 的 ContainsUndefinedBreakTarget 。
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 hasUndefinedLabels 为以参数 labelSet 调用第一个 Statement 的 ContainsUndefinedBreakTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 labelSet 调用第二个 Statement 的 ContainsUndefinedBreakTarget 。
IfStatement :
if
(
Expression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsUndefinedBreakTarget 。
DoWhileStatement :
do
Statement
while
(
Expression
)
;
返回以参数 labelSet 调用 Statement 的 ContainsUndefinedBreakTarget 。
WhileStatement :
while
(
Expression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsUndefinedBreakTarget 。
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsUndefinedBreakTarget 。
ForInOfStatement :
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
var
ForBinding
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsUndefinedBreakTarget 。
注
BreakStatement :
break
;
返回 false 。
BreakStatement :
break
LabelIdentifier
;
如果 labelSet 不包含 LabelIdentifier 的 StringValue ,返回
true 。
返回 false 。
WithStatement :
with
(
Expression
)
Statement
返回以参数 labelSet 调用 Statement 的 ContainsUndefinedBreakTarget 。
SwitchStatement :
switch
(
Expression
)
CaseBlock
返回以参数 labelSet 调用 CaseBlock 的 ContainsUndefinedBreakTarget 。
CaseBlock :
{
}
返回 false 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,那么
如果以参数 labelSet 调用第一个 CaseClauses 的 ContainsUndefinedBreakTarget
是 true ,返回 true 。
如果以参数 labelSet 调用 DefaultClause 的 ContainsUndefinedBreakTarget
是 true ,返回 true 。
如果第二个 CaseClauses
不存在,返回 false 。
返回以参数 labelSet 调用第二个 CaseClauses 的 ContainsUndefinedBreakTarget 。
CaseClauses :
CaseClauses
CaseClause
令 hasUndefinedLabels 为以参数 labelSet 调用 CaseClauses 的 ContainsUndefinedBreakTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 labelSet 调用 CaseClause 的 ContainsUndefinedBreakTarget 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,返回以参数 labelSet 调用 StatementList 的 ContainsUndefinedBreakTarget 。
返回 false 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,返回以参数 labelSet 调用 StatementList 的 ContainsUndefinedBreakTarget 。
返回 false 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
令 label 为 LabelIdentifier 的 StringValue 。
令 newLabelSet 为 labelSet 和 « label » 的 列表连接 。
返回以参数 newLabelSet 调用 LabelledItem 的 ContainsUndefinedBreakTarget 。
LabelledItem : FunctionDeclaration
返回 false 。
TryStatement :
try
Block
Catch
令 hasUndefinedLabels 为以参数 labelSet 调用 Block 的 ContainsUndefinedBreakTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 labelSet 调用 Catch 的 ContainsUndefinedBreakTarget 。
TryStatement :
try
Block
Finally
令 hasUndefinedLabels 为以参数 labelSet 调用 Block 的 ContainsUndefinedBreakTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 labelSet 调用 Finally 的 ContainsUndefinedBreakTarget 。
TryStatement :
try
Block
Catch
Finally
如果以参数 labelSet 调用 Block 的 ContainsUndefinedBreakTarget
是 true ,返回 true 。
如果以参数 labelSet 调用 Catch 的 ContainsUndefinedBreakTarget
是 true ,返回 true 。
返回以参数 labelSet 调用 Finally 的 ContainsUndefinedBreakTarget 。
Catch :
catch
(
CatchParameter
)
Block
返回以参数 labelSet 调用 Block 的 ContainsUndefinedBreakTarget 。
FunctionStatementList
: [empty]
返回 false 。
ClassStaticBlockStatementList
: [empty]
返回 false 。
ModuleItemList :
ModuleItemList
ModuleItem
令 hasUndefinedLabels 为以参数 labelSet 调用 ModuleItemList 的 ContainsUndefinedBreakTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 labelSet 调用 ModuleItem 的 ContainsUndefinedBreakTarget 。
ModuleItem :
ImportDeclaration
ExportDeclaration
返回 false 。
8.3.3 静态语义:ContainsUndefinedContinueTarget
语法导向操作
ContainsUndefinedContinueTarget 接受参数
iterationSet (一个字符串的 列表 )和
labelSet (一个字符串的 列表 )并返回一个布尔值。它在以下产生式上分段定义:
Statement :
VariableStatement
EmptyStatement
ExpressionStatement
BreakStatement
ReturnStatement
ThrowStatement
DebuggerStatement
Block :
{
}
StatementListItem
:
Declaration
返回 false 。
Statement : BlockStatement
返回以参数 iterationSet 和 « » 调用 BlockStatement 的 ContainsUndefinedContinueTarget 。
BreakableStatement
: IterationStatement
令 newIterationSet 为 iterationSet 和 labelSet 的 列表连接 。
返回以参数 newIterationSet 和 « » 调用 IterationStatement 的 ContainsUndefinedContinueTarget 。
StatementList :
StatementList
StatementListItem
令 hasUndefinedLabels 为以参数 iterationSet 和 « » 调用 StatementList 的 ContainsUndefinedContinueTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用 StatementListItem 的 ContainsUndefinedContinueTarget 。
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 hasUndefinedLabels 为以参数 iterationSet 和 « » 调用第一个 Statement 的 ContainsUndefinedContinueTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用第二个 Statement 的 ContainsUndefinedContinueTarget 。
IfStatement :
if
(
Expression
)
Statement
返回以参数 iterationSet 和 « » 调用 Statement 的 ContainsUndefinedContinueTarget 。
DoWhileStatement :
do
Statement
while
(
Expression
)
;
返回以参数 iterationSet 和 « » 调用 Statement 的 ContainsUndefinedContinueTarget 。
WhileStatement :
while
(
Expression
)
Statement
返回以参数 iterationSet 和 « » 调用 Statement 的 ContainsUndefinedContinueTarget 。
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
返回以参数 iterationSet 和 « » 调用 Statement 的 ContainsUndefinedContinueTarget 。
ForInOfStatement :
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
var
ForBinding
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
返回以参数 iterationSet 和 « » 调用 Statement 的 ContainsUndefinedContinueTarget 。
注
ContinueStatement
:
continue
;
返回 false 。
ContinueStatement
:
continue
LabelIdentifier
;
如果 iterationSet 不包含 LabelIdentifier 的 StringValue ,返回
true 。
返回 false 。
WithStatement :
with
(
Expression
)
Statement
返回以参数 iterationSet 和 « » 调用 Statement 的 ContainsUndefinedContinueTarget 。
SwitchStatement :
switch
(
Expression
)
CaseBlock
返回以参数 iterationSet 和 « » 调用 CaseBlock 的 ContainsUndefinedContinueTarget 。
CaseBlock :
{
}
返回 false 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
如果第一个 CaseClauses 存在,那么
如果以参数 iterationSet 和 « » 调用第一个 CaseClauses 的 ContainsUndefinedContinueTarget
是 true ,返回 true 。
如果以参数 iterationSet 和 « » 调用 DefaultClause 的 ContainsUndefinedContinueTarget
是 true ,返回 true 。
如果第二个 CaseClauses
不存在,返回 false 。
返回以参数 iterationSet 和 « » 调用第二个 CaseClauses 的 ContainsUndefinedContinueTarget 。
CaseClauses :
CaseClauses
CaseClause
令 hasUndefinedLabels 为以参数 iterationSet 和 « » 调用 CaseClauses 的 ContainsUndefinedContinueTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用 CaseClause 的 ContainsUndefinedContinueTarget 。
CaseClause :
case
Expression
:
StatementList opt
如果 StatementList
存在,返回以参数 iterationSet 和 « » 调用 StatementList 的 ContainsUndefinedContinueTarget 。
返回 false 。
DefaultClause :
default
:
StatementList opt
如果 StatementList
存在,返回以参数 iterationSet 和 « » 调用 StatementList 的 ContainsUndefinedContinueTarget 。
返回 false 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
令 label 为 LabelIdentifier 的 StringValue 。
令 newLabelSet 为 labelSet 和 « label » 的 列表连接 。
返回以参数 iterationSet 和 newLabelSet 调用 LabelledItem 的 ContainsUndefinedContinueTarget 。
LabelledItem : FunctionDeclaration
返回 false 。
TryStatement :
try
Block
Catch
令 hasUndefinedLabels 为以参数 iterationSet 和 « » 调用 Block 的 ContainsUndefinedContinueTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用 Catch 的 ContainsUndefinedContinueTarget 。
TryStatement :
try
Block
Finally
令 hasUndefinedLabels 为以参数 iterationSet 和 « » 调用 Block 的 ContainsUndefinedContinueTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用 Finally 的 ContainsUndefinedContinueTarget 。
TryStatement :
try
Block
Catch
Finally
如果以参数 iterationSet 和 « » 调用 Block 的 ContainsUndefinedContinueTarget
是 true ,返回 true 。
如果以参数 iterationSet 和 « » 调用 Catch 的 ContainsUndefinedContinueTarget
是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用 Finally 的 ContainsUndefinedContinueTarget 。
Catch :
catch
(
CatchParameter
)
Block
返回以参数 iterationSet 和 « » 调用 Block 的 ContainsUndefinedContinueTarget 。
FunctionStatementList
: [empty]
返回 false 。
ClassStaticBlockStatementList
: [empty]
返回 false 。
ModuleItemList :
ModuleItemList
ModuleItem
令 hasUndefinedLabels 为以参数 iterationSet 和 « » 调用 ModuleItemList 的
ContainsUndefinedContinueTarget 。
如果 hasUndefinedLabels 是 true ,返回 true 。
返回以参数 iterationSet 和 « » 调用 ModuleItem 的 ContainsUndefinedContinueTarget 。
ModuleItem :
ImportDeclaration
ExportDeclaration
返回 false 。
8.4 函数名推断
8.4.1 静态语义:HasName
语法导向操作
HasName 不接受任何参数并返回一个布尔值。它在以下产生式上分段定义:
PrimaryExpression
: CoverParenthesizedExpressionAndArrowParameterList
令 expr 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ParenthesizedExpression 。
如果 expr 的 IsFunctionDefinition
是 false ,返回 false 。
返回 expr 的 HasName 。
FunctionExpression
:
function
(
FormalParameters
)
{
FunctionBody
}
GeneratorExpression
:
function
*
(
FormalParameters
)
{
GeneratorBody
}
AsyncGeneratorExpression
:
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncFunctionExpression
:
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
ArrowFunction :
ArrowParameters
=>
ConciseBody
AsyncArrowFunction
:
async
AsyncArrowBindingIdentifier
=>
AsyncConciseBody
CoverCallExpressionAndAsyncArrowHead
=>
AsyncConciseBody
ClassExpression :
class
ClassTail
返回 false 。
FunctionExpression
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
GeneratorExpression
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
AsyncGeneratorExpression
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncFunctionExpression
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
ClassExpression :
class
BindingIdentifier
ClassTail
返回 true 。
8.4.2 静态语义:IsFunctionDefinition
语法导向操作
IsFunctionDefinition 不接受任何参数并返回一个布尔值。它在以下产生式上分段定义:
PrimaryExpression
: CoverParenthesizedExpressionAndArrowParameterList
令 expr 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ParenthesizedExpression 。
返回 expr 的 IsFunctionDefinition 。
PrimaryExpression
:
this
IdentifierReference
Literal
ArrayLiteral
ObjectLiteral
RegularExpressionLiteral
TemplateLiteral
MemberExpression :
MemberExpression
[
Expression
]
MemberExpression
.
IdentifierName
MemberExpression
TemplateLiteral
SuperProperty
MetaProperty
new
MemberExpression
Arguments
MemberExpression
.
PrivateIdentifier
NewExpression :
new
NewExpression
LeftHandSideExpression
:
CallExpression
OptionalExpression
UpdateExpression :
LeftHandSideExpression
++
LeftHandSideExpression
--
++
UnaryExpression
--
UnaryExpression
UnaryExpression :
delete
UnaryExpression
void
UnaryExpression
typeof
UnaryExpression
+
UnaryExpression
-
UnaryExpression
~
UnaryExpression
!
UnaryExpression
AwaitExpression
ExponentiationExpression
:
UpdateExpression
**
ExponentiationExpression
MultiplicativeExpression
:
MultiplicativeExpression
MultiplicativeOperator
ExponentiationExpression
AdditiveExpression
:
AdditiveExpression
+
MultiplicativeExpression
AdditiveExpression
-
MultiplicativeExpression
ShiftExpression :
ShiftExpression
<<
AdditiveExpression
ShiftExpression
>>
AdditiveExpression
ShiftExpression
>>>
AdditiveExpression
RelationalExpression
:
RelationalExpression
<
ShiftExpression
RelationalExpression
>
ShiftExpression
RelationalExpression
<=
ShiftExpression
RelationalExpression
>=
ShiftExpression
RelationalExpression
instanceof
ShiftExpression
RelationalExpression
in
ShiftExpression
PrivateIdentifier
in
ShiftExpression
EqualityExpression
:
EqualityExpression
==
RelationalExpression
EqualityExpression
!=
RelationalExpression
EqualityExpression
===
RelationalExpression
EqualityExpression
!==
RelationalExpression
BitwiseANDExpression
:
BitwiseANDExpression
&
EqualityExpression
BitwiseXORExpression
:
BitwiseXORExpression
^
BitwiseANDExpression
BitwiseORExpression
:
BitwiseORExpression
|
BitwiseXORExpression
LogicalANDExpression
:
LogicalANDExpression
&&
BitwiseORExpression
LogicalORExpression
:
LogicalORExpression
||
LogicalANDExpression
CoalesceExpression
:
CoalesceExpressionHead
??
BitwiseORExpression
ConditionalExpression
:
ShortCircuitExpression
?
AssignmentExpression
:
AssignmentExpression
AssignmentExpression
:
YieldExpression
LeftHandSideExpression
=
AssignmentExpression
LeftHandSideExpression
AssignmentOperator
AssignmentExpression
LeftHandSideExpression
&&=
AssignmentExpression
LeftHandSideExpression
||=
AssignmentExpression
LeftHandSideExpression
??=
AssignmentExpression
Expression :
Expression
,
AssignmentExpression
返回 false 。
AssignmentExpression
:
ArrowFunction
AsyncArrowFunction
FunctionExpression
:
function
BindingIdentifier opt
(
FormalParameters
)
{
FunctionBody
}
GeneratorExpression
:
function
*
BindingIdentifier opt
(
FormalParameters
)
{
GeneratorBody
}
AsyncGeneratorExpression
:
async
function
*
BindingIdentifier opt
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncFunctionExpression
:
async
function
BindingIdentifier opt
(
FormalParameters
)
{
AsyncFunctionBody
}
ClassExpression :
class
BindingIdentifier opt
ClassTail
返回 true 。
8.4.3 静态语义:IsAnonymousFunctionDefinition (
expr )
抽象操作 IsAnonymousFunctionDefinition 接受参数 expr (一个 AssignmentExpression
解析节点 、一个 Initializer 解析节点 ,或一个 Expression 解析节点 )并返回一个布尔值。它确定其参数是否为不绑定名称的函数定义。当被调用时执行以下步骤:
如果 expr 的 IsFunctionDefinition
是 false ,返回 false 。
令 hasName 为 expr 的 HasName 。
如果 hasName 是 true ,返回 false 。
返回 true 。
8.4.4 静态语义:IsIdentifierRef
语法导向操作
IsIdentifierRef 不接受任何参数并返回一个布尔值。它在以下产生式上分段定义:
PrimaryExpression
: IdentifierReference
返回 true 。
PrimaryExpression
:
this
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
AsyncFunctionExpression
AsyncGeneratorExpression
RegularExpressionLiteral
TemplateLiteral
CoverParenthesizedExpressionAndArrowParameterList
MemberExpression :
MemberExpression
[
Expression
]
MemberExpression
.
IdentifierName
MemberExpression
TemplateLiteral
SuperProperty
MetaProperty
new
MemberExpression
Arguments
MemberExpression
.
PrivateIdentifier
NewExpression :
new
NewExpression
LeftHandSideExpression
:
CallExpression
OptionalExpression
返回 false 。
8.4.5 运行时语义:NamedEvaluation
语法导向操作
NamedEvaluation 接受参数 name (一个 属性键 或一个 私有名称 )并返回要么 包含 函数对象 的正常完成,要么 中断完成 。它在以下产生式上分段定义:
PrimaryExpression
: CoverParenthesizedExpressionAndArrowParameterList
令 expr 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ParenthesizedExpression 。
返回 ? expr 以参数 name 执行的 NamedEvaluation 。
ParenthesizedExpression
:
(
Expression
)
断言 :
IsAnonymousFunctionDefinition (Expression ) 是
true 。
返回 ? Expression 以参数
name 执行的 NamedEvaluation 。
FunctionExpression
:
function
(
FormalParameters
)
{
FunctionBody
}
返回 FunctionExpression 以参数
name 执行的 InstantiateOrdinaryFunctionExpression 。
GeneratorExpression
:
function
*
(
FormalParameters
)
{
GeneratorBody
}
返回 GeneratorExpression 以参数
name 执行的 InstantiateGeneratorFunctionExpression 。
AsyncGeneratorExpression
:
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
返回 AsyncGeneratorExpression 以参数
name 执行的 InstantiateAsyncGeneratorFunctionExpression 。
AsyncFunctionExpression
:
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 AsyncFunctionExpression 以参数
name 执行的 InstantiateAsyncFunctionExpression 。
ArrowFunction :
ArrowParameters
=>
ConciseBody
返回 ArrowFunction 以参数
name 执行的 InstantiateArrowFunctionExpression 。
AsyncArrowFunction
:
async
AsyncArrowBindingIdentifier
=>
AsyncConciseBody
CoverCallExpressionAndAsyncArrowHead
=>
AsyncConciseBody
返回 AsyncArrowFunction 以参数
name 执行的 InstantiateAsyncArrowFunctionExpression 。
ClassExpression :
class
ClassTail
令 value 为 ? ClassTail 以参数
undefined 和 name 执行的 ClassDefinitionEvaluation 。
设置 value .[[SourceText]] 为 ClassExpression 匹配的源文本 。
返回 value 。
8.5 包含 (Contains)
8.5.1 静态语义:包含 (Contains)
语法导向操作 包含
(Contains) 接受参数 symbol (一个语法符号) 并返回一个布尔值。
本规范中所有未在下面列出的语法产生式备选都隐式具有以下 包含 (Contains) 的默认定义:
对于此 解析节点 的每个子节点 child ,执行:
如果 child 是 symbol 的实例,返回 true 。
如果 child 是一个非终结符的实例,则:
令 contained 为 child 包含
symbol 的结果。
如果 contained 为 true ,返回
true 。
返回 false 。
函数声明
:
function
绑定标识符
(
形式参数
)
{
函数体
}
function
(
形式参数
)
{
函数体
}
函数表达式
:
function
绑定标识符 opt
(
形式参数
)
{
函数体
}
生成器声明
:
function
*
绑定标识符
(
形式参数
)
{
生成器体
}
function
*
(
形式参数
)
{
生成器体
}
生成器表达式
:
function
*
绑定标识符 opt
(
形式参数
)
{
生成器体
}
异步生成器声明
:
async
function
*
绑定标识符
(
形式参数
)
{
异步生成器体
}
async
function
*
(
形式参数
)
{
异步生成器体
}
异步生成器表达式
:
async
function
*
绑定标识符 opt
(
形式参数
)
{
异步生成器体
}
异步函数声明
:
async
function
绑定标识符
(
形式参数
)
{
异步函数体
}
async
function
(
形式参数
)
{
异步函数体
}
异步函数表达式
:
async
function
绑定标识符 opt
(
形式参数
)
{
异步函数体
}
返回 false 。
注 1
类尾 :
类继承 opt
{
类体
}
如果 symbol 是 类体 ,返回 true 。
如果 symbol 是 类继承 ,则:
如果 类继承 存在,返回
true ;否则返回 false 。
如果 类继承 存在,则:
如果 类继承
包含
symbol 为 true ,返回 true 。
返回以 symbol 为参数的 类体 的 计算属性包含 的结果。
注 2
依赖于子结构的静态语义规则通常不深入类体,除了 属性名 。
类静态块 :
static
{
类静态块体
}
返回 false 。
注 3
依赖于子结构的静态语义规则通常不深入 static 初始化块。
箭头函数 :
箭头参数
=>
简洁体
如果 symbol 不是 NewTarget 、SuperProperty 、SuperCall 、super 或
this 之一,返回 false 。
如果 箭头参数 包含 symbol 为
true ,返回 true 。
返回 简洁体 包含 symbol 。
箭头参数 :
覆盖带括号的表达式和箭头参数列表
令 formals 为被 覆盖带括号的表达式和箭头参数列表
覆盖 的 箭头形式参数 。
返回 formals 包含 symbol 。
异步箭头函数
:
async
异步箭头绑定标识符
=>
异步简洁体
如果 symbol 不是 NewTarget 、SuperProperty 、SuperCall 、super 或
this 之一,返回 false 。
返回 异步简洁体 包含 symbol 。
异步箭头函数
:
覆盖调用表达式和异步箭头头部
=>
异步简洁体
如果 symbol 不是 NewTarget 、SuperProperty 、SuperCall 、super 或
this 之一,返回 false 。
令 head 为被 覆盖调用表达式和异步箭头头部
覆盖 的 异步箭头头部 。
如果 head 包含 symbol 为
true ,返回 true 。
返回 异步简洁体 包含 symbol 。
注 4
包含 (Contains) 用于检测 箭头函数 或 异步箭头函数 中
new.target、this 和 super 的使用情况。
属性定义
: 方法定义
如果 symbol 是 方法定义 ,返回 true 。
返回以 symbol 为参数的 方法定义 的 计算属性包含 的结果。
字面量属性名
: 标识符名称
返回 false 。
成员表达式 :
成员表达式
.
标识符名称
如果 成员表达式 包含 symbol 为
true ,返回 true 。
返回 false 。
Super属性 :
super
.
标识符名称
如果 symbol 是 保留字 super,返回
true 。
返回 false 。
调用表达式 :
调用表达式
.
标识符名称
如果 调用表达式 包含 symbol 为
true ,返回 true 。
返回 false 。
可选链 :
?.
标识符名称
返回 false 。
可选链 :
可选链
.
标识符名称
如果 可选链 包含 symbol 为
true ,返回 true 。
返回 false 。
8.5.2 静态语义:计算属性包含 (ComputedPropertyContains)
语法导向操作
计算属性包含 (ComputedPropertyContains) 接受参数 symbol (一个语法符号) 并返回一个布尔值。它在以下产生式中分段定义:
类元素名称 :
私有标识符
属性名 : 字面量属性名
返回 false 。
属性名 : 计算属性名
返回 计算属性名
包含 symbol 的结果。
方法定义 :
类元素名称
(
唯一形式参数
)
{
函数体
}
get
类元素名称
(
)
{
函数体
}
set
类元素名称
(
属性设置器参数列表
)
{
函数体
}
返回以 symbol 为参数的 类元素名称 的 计算属性包含 的结果。
生成器方法 :
*
类元素名称
(
唯一形式参数
)
{
生成器体
}
返回以 symbol 为参数的 类元素名称 的 计算属性包含 的结果。
异步生成器方法
:
async
*
类元素名称
(
唯一形式参数
)
{
异步生成器体
}
返回以 symbol 为参数的 类元素名称 的 计算属性包含 的结果。
类元素列表 :
类元素列表
类元素
令 inList 为以 symbol 为参数的 类元素列表 的 计算属性包含 。
如果 inList 为 true ,返回 true 。
返回以 symbol 为参数的 类元素 的 计算属性包含 的结果。
类元素 : 类静态块
返回 false 。
类元素 : ;
返回 false 。
异步方法 :
async
类元素名称
(
唯一形式参数
)
{
异步函数体
}
返回以 symbol 为参数的 类元素名称 的 计算属性包含 的结果。
字段定义 :
类元素名称
初始化器 opt
返回以 symbol 为参数的 类元素名称 的 计算属性包含 的结果。
8.6 杂项
这些操作在规范中的多个地方使用。
8.6.1 运行时语义:InstantiateFunctionObject
语法导向操作
InstantiateFunctionObject 接收参数 env (一个 环境记录 ) 和
privateEnv (一个 私有环境记录 或 null ),并返回一个
ECMAScript 函数对象 。它在以下产生式上分段定义:
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
function
(
FormalParameters
)
{
FunctionBody
}
返回 InstantiateOrdinaryFunctionObject ,其参数为
FunctionDeclaration ,以及参数
env 和 privateEnv 。
GeneratorDeclaration
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
function
*
(
FormalParameters
)
{
GeneratorBody
}
返回 InstantiateGeneratorFunctionObject ,其参数为
GeneratorDeclaration ,以及参数
env 和 privateEnv 。
AsyncGeneratorDeclaration
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
返回 InstantiateAsyncGeneratorFunctionObject ,其参数为
AsyncGeneratorDeclaration ,以及参数
env 和 privateEnv 。
AsyncFunctionDeclaration
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 InstantiateAsyncFunctionObject ,其参数为
AsyncFunctionDeclaration ,以及参数
env 和 privateEnv 。
8.6.2 运行时语义:BindingInitialization
语法导向操作
BindingInitialization 接受参数 value (一个 ECMAScript 语言值 )和
environment (一个 环境记录 或
undefined ),并返回一个
包含
unused 的正常完成,或者一个 异常完成 。
注意
undefined 作为 environment 传递,以指示应使用 PutValue
操作来分配初始化值。对于 var 语句和某些 非严格函数
的形式参数列表(参见 10.2.11 )就是这种情况。在这些情况下,词法绑定会在其初始化程序的评估之前被提升和预初始化。
它在以下产生式上分段定义:
BindingIdentifier
: Identifier
令 name 为 Identifier 的 StringValue 。
返回 ? InitializeBoundName (name ,
value , environment ).
BindingIdentifier
: yield
返回 ? InitializeBoundName ("yield" ,
value , environment ).
BindingIdentifier
: await
返回 ? InitializeBoundName ("await" ,
value , environment ).
BindingPattern :
ObjectBindingPattern
执行 ? RequireObjectCoercible (value ).
返回 ? BindingInitialization (ObjectBindingPattern with
arguments value 和 environment .
BindingPattern :
ArrayBindingPattern
令 iteratorRecord 为 ? GetIterator (value ,
sync ).
令 result 为 Completion (IteratorBindingInitialization of ArrayBindingPattern
with arguments iteratorRecord 和 environment ).
如果 iteratorRecord .[[Done]] 为
false ,则返回 ? IteratorClose (iteratorRecord ,
result ).
返回 ? result .
ObjectBindingPattern
:
{
}
返回 unused .
ObjectBindingPattern
:
{
BindingPropertyList
}
{
BindingPropertyList
,
}
执行 ? PropertyBindingInitialization (BindingPropertyList
with arguments value 和 environment .
返回 unused .
ObjectBindingPattern
:
{
BindingRestProperty
}
令 excludedNames 为一个新的空 列表 。
返回 ? RestBindingInitialization (BindingRestProperty
with arguments value , environment , 和 excludedNames .
ObjectBindingPattern
:
{
BindingPropertyList
,
BindingRestProperty
}
令 excludedNames 为 ? PropertyBindingInitialization (BindingPropertyList
with arguments value 和 environment .
返回 ? RestBindingInitialization (BindingRestProperty
with arguments value , environment , 和 excludedNames .
8.6.2.1 InitializeBoundName ( name , value ,
environment )
抽象操作 InitializeBoundName 接受参数 name (一个字符串)、value (一个
ECMAScript 语言值 )和
environment (一个 环境记录 或
undefined ),并返回一个
包含
unused 的正常完成,或者一个 异常完成 。调用时,它执行以下步骤:
如果 environment 不是 undefined ,则:
执行 ! environment .InitializeBinding(name ,
value ).
返回 unused .
否则:
令 lhs 为 ? ResolveBinding (name ).
返回 ? PutValue (lhs ,
value ).
8.6.3 运行时语义:IteratorBindingInitialization
语法导向操作
IteratorBindingInitialization 接受参数
iteratorRecord (一个迭代器记录 )和 environment
(一个环境记录 或
undefined ),并返回包含
unused 的正常完成 或异常完成 。
注
当 environment 传递 undefined 时,表示应该使用PutValue
操作来分配初始化值。这是非严格函数 的形式参数列表的情况。在这种情况下,形式参数绑定被预初始化,以处理具有相同名称的多个参数的可能性。
它在以下产生式上分段定义:
ArrayBindingPattern
:
[
]
返回 unused 。
ArrayBindingPattern
:
[
Elision
]
返回 ? IteratorDestructuringAssignmentEvaluation of
Elision with argument
iteratorRecord 。
ArrayBindingPattern
:
[
Elision opt
BindingRestElement
]
如果 Elision 存在,则
执行 ? IteratorDestructuringAssignmentEvaluation
of Elision with
argument iteratorRecord 。
返回 ? IteratorBindingInitialization of BindingRestElement
with arguments iteratorRecord and environment 。
ArrayBindingPattern
:
[
BindingElementList
,
Elision
]
执行 ? IteratorBindingInitialization of BindingElementList
with arguments iteratorRecord and environment 。
返回 ? IteratorDestructuringAssignmentEvaluation of
Elision with argument
iteratorRecord 。
ArrayBindingPattern
:
[
BindingElementList
,
Elision opt
BindingRestElement
]
执行 ? IteratorBindingInitialization of BindingElementList
with arguments iteratorRecord and environment 。
如果 Elision 存在,则
执行 ? IteratorDestructuringAssignmentEvaluation
of Elision with
argument iteratorRecord 。
返回 ? IteratorBindingInitialization of BindingRestElement
with arguments iteratorRecord and environment 。
BindingElementList
:
BindingElementList
,
BindingElisionElement
执行 ? IteratorBindingInitialization of BindingElementList
with arguments iteratorRecord and environment 。
返回 ? IteratorBindingInitialization of BindingElisionElement with
arguments iteratorRecord and environment 。
BindingElisionElement
:
Elision
BindingElement
执行 ? IteratorDestructuringAssignmentEvaluation of
Elision with argument
iteratorRecord 。
返回 ? IteratorBindingInitialization of BindingElement with
arguments iteratorRecord and environment 。
SingleNameBinding
:
BindingIdentifier
Initializer opt
设 bindingId 为 BindingIdentifier 的StringValue 。
设 lhs 为 ? ResolveBinding (bindingId ,
environment )。
设 v 为 undefined 。
如果 iteratorRecord .[[Done]] 是
false ,则
设 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 不是 done ,则
设置 v 为 next 。
如果 Initializer 存在且
v 是 undefined ,则
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true ,则
设置 v 为 ? NamedEvaluation of Initializer
with argument bindingId 。
否则,
设 defaultValue 为 ? Evaluation of Initializer 。
设置 v 为 ? GetValue (defaultValue )。
如果 environment 是 undefined ,则返回 ? PutValue (lhs , v )。
返回 ? InitializeReferencedBinding (lhs ,
v )。
BindingElement :
BindingPattern
Initializer opt
设 v 为 undefined 。
如果 iteratorRecord .[[Done]] 是
false ,则
设 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 不是 done ,则
设置 v 为 next 。
如果 Initializer 存在且
v 是 undefined ,则
设 defaultValue 为 ? Evaluation of
Initializer 。
设置 v 为 ? GetValue (defaultValue )。
返回 ? BindingInitialization of BindingPattern with
arguments v and environment 。
BindingRestElement
:
...
BindingIdentifier
设 lhs 为 ? ResolveBinding (BindingIdentifier 的StringValue ,
environment )。
设 A 为 ! ArrayCreate (0)。
设 n 为 0。
重复,
设 next 为 done 。
如果 iteratorRecord .[[Done]] 是
false ,则
设置 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,则
如果 environment 是 undefined ,则返回
? PutValue (lhs ,
A )。
返回 ? InitializeReferencedBinding (lhs ,
A )。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )),
next )。
设置 n 为 n + 1。
BindingRestElement
:
...
BindingPattern
设 A 为 ! ArrayCreate (0)。
设 n 为 0。
重复,
设 next 为 done 。
如果 iteratorRecord .[[Done]] 是
false ,则
设置 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,则
返回 ? BindingInitialization of
BindingPattern with
arguments A and environment 。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )),
next )。
设置 n 为 n + 1。
FormalParameters :
[empty]
返回 unused 。
FormalParameters :
FormalParameterList
,
FunctionRestParameter
执行 ? IteratorBindingInitialization of FormalParameterList
with arguments iteratorRecord and environment 。
返回 ? IteratorBindingInitialization of FunctionRestParameter with
arguments iteratorRecord and environment 。
FormalParameterList
:
FormalParameterList
,
FormalParameter
执行 ? IteratorBindingInitialization of FormalParameterList
with arguments iteratorRecord and environment 。
返回 ? IteratorBindingInitialization of FormalParameter with
arguments iteratorRecord and environment 。
ArrowParameters :
BindingIdentifier
设 v 为 undefined 。
断言 :
iteratorRecord .[[Done]] 是 false 。
设 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 不是 done ,则
设置 v 为 next 。
返回 ? BindingInitialization of BindingIdentifier
with arguments v and environment 。
ArrowParameters :
CoverParenthesizedExpressionAndArrowParameterList
设 formals 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的ArrowFormalParameters 。
返回 ? IteratorBindingInitialization of
formals with arguments iteratorRecord and environment 。
AsyncArrowBindingIdentifier
: BindingIdentifier
设 v 为 undefined 。
断言 :
iteratorRecord .[[Done]] 是 false 。
设 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 不是 done ,则
设置 v 为 next 。
返回 ? BindingInitialization of BindingIdentifier
with arguments v and environment 。
8.6.4 静态语义:AssignmentTargetType
语法导向操作
AssignmentTargetType 不接受参数并返回
simple 或 invalid 。它在以下产生式上分段定义:
IdentifierReference
: Identifier
如果 IsStrict (this IdentifierReference ) 是
true 且 Identifier 的 StringValue 是
"eval" 或 "arguments" ,返回
invalid 。
返回 simple 。
IdentifierReference
:
yield
await
CallExpression :
CallExpression
[
Expression
]
CallExpression
.
IdentifierName
CallExpression
.
PrivateIdentifier
MemberExpression :
MemberExpression
[
Expression
]
MemberExpression
.
IdentifierName
SuperProperty
MemberExpression
.
PrivateIdentifier
返回 simple 。
PrimaryExpression
:
CoverParenthesizedExpressionAndArrowParameterList
设 expr 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ParenthesizedExpression 。
返回 expr 的 AssignmentTargetType 。
PrimaryExpression
:
this
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
AsyncFunctionExpression
AsyncGeneratorExpression
RegularExpressionLiteral
TemplateLiteral
CallExpression :
CoverCallExpressionAndAsyncArrowHead
SuperCall
ImportCall
CallExpression
Arguments
CallExpression
TemplateLiteral
NewExpression :
new
NewExpression
MemberExpression :
MemberExpression
TemplateLiteral
new
MemberExpression
Arguments
NewTarget :
new
.
target
ImportMeta :
import
.
meta
LeftHandSideExpression
:
OptionalExpression
UpdateExpression :
LeftHandSideExpression
++
LeftHandSideExpression
--
++
UnaryExpression
--
UnaryExpression
UnaryExpression :
delete
UnaryExpression
void
UnaryExpression
typeof
UnaryExpression
+
UnaryExpression
-
UnaryExpression
~
UnaryExpression
!
UnaryExpression
AwaitExpression
ExponentiationExpression
:
UpdateExpression
**
ExponentiationExpression
MultiplicativeExpression
:
MultiplicativeExpression
MultiplicativeOperator
ExponentiationExpression
AdditiveExpression
:
AdditiveExpression
+
MultiplicativeExpression
AdditiveExpression
-
MultiplicativeExpression
ShiftExpression :
ShiftExpression
<<
AdditiveExpression
ShiftExpression
>>
AdditiveExpression
ShiftExpression
>>>
AdditiveExpression
RelationalExpression
:
RelationalExpression
<
ShiftExpression
RelationalExpression
>
ShiftExpression
RelationalExpression
<=
ShiftExpression
RelationalExpression
>=
ShiftExpression
RelationalExpression
instanceof
ShiftExpression
RelationalExpression
in
ShiftExpression
PrivateIdentifier
in
ShiftExpression
EqualityExpression
:
EqualityExpression
==
RelationalExpression
EqualityExpression
!=
RelationalExpression
EqualityExpression
===
RelationalExpression
EqualityExpression
!==
RelationalExpression
BitwiseANDExpression
:
BitwiseANDExpression
&
EqualityExpression
BitwiseXORExpression
:
BitwiseXORExpression
^
BitwiseANDExpression
BitwiseORExpression
:
BitwiseORExpression
|
BitwiseXORExpression
LogicalANDExpression
:
LogicalANDExpression
&&
BitwiseORExpression
LogicalORExpression
:
LogicalORExpression
||
LogicalANDExpression
CoalesceExpression
:
CoalesceExpressionHead
??
BitwiseORExpression
ConditionalExpression
:
ShortCircuitExpression
?
AssignmentExpression
:
AssignmentExpression
AssignmentExpression
:
YieldExpression
ArrowFunction
AsyncArrowFunction
LeftHandSideExpression
=
AssignmentExpression
LeftHandSideExpression
AssignmentOperator
AssignmentExpression
LeftHandSideExpression
&&=
AssignmentExpression
LeftHandSideExpression
||=
AssignmentExpression
LeftHandSideExpression
??=
AssignmentExpression
Expression :
Expression
,
AssignmentExpression
返回 invalid 。
8.6.5 静态语义:PropName
语法导向操作
PropName 不接受参数并返回一个字符串或
empty 。它在以下产生式上分段定义:
PropertyDefinition
: IdentifierReference
返回 IdentifierReference 的 StringValue 。
PropertyDefinition
:
...
AssignmentExpression
返回 empty 。
PropertyDefinition
:
PropertyName
:
AssignmentExpression
返回 PropertyName 的
PropName 。
LiteralPropertyName
: IdentifierName
AttributeKey : IdentifierName
返回 IdentifierName 的
StringValue 。
LiteralPropertyName
: StringLiteral
AttributeKey : StringLiteral
返回 StringLiteral 的
SV 。
LiteralPropertyName
: NumericLiteral
设 nbr 为 NumericLiteral 的 NumericValue 。
返回 ! ToString (nbr )。
ComputedPropertyName
:
[
AssignmentExpression
]
返回 empty 。
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
get
ClassElementName
(
)
{
FunctionBody
}
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
返回 ClassElementName 的 PropName 。
GeneratorMethod :
*
ClassElementName
(
UniqueFormalParameters
)
{
GeneratorBody
}
返回 ClassElementName 的 PropName 。
AsyncGeneratorMethod
:
async
*
ClassElementName
(
UniqueFormalParameters
)
{
AsyncGeneratorBody
}
返回 ClassElementName 的 PropName 。
ClassElement : ClassStaticBlock
返回 empty 。
ClassElement : ;
返回 empty 。
AsyncMethod :
async
ClassElementName
(
UniqueFormalParameters
)
{
AsyncFunctionBody
}
返回 ClassElementName 的 PropName 。
FieldDefinition :
ClassElementName
Initializer opt
返回 ClassElementName 的 PropName 。
ClassElementName :
PrivateIdentifier
返回 empty 。
9 可执行代码和执行上下文
9.1 环境记录
环境记录 是一种规范类型,
用于定义标识符 与特定变量和函数的关联,基于
ECMAScript代码的词法嵌套结构。通常环境记录与ECMAScript代码的某些特定语法结构相关联,
如函数声明 、块语句 或try语句 的catch 子句。每次求值这样的代码时,
都会创建一个新的环境记录来记录该代码创建的标识符绑定。
每个环境记录都有一个[[OuterEnv]] 字段,它要么是
null ,要么是对外部环境记录的引用。这用于建模环境记录值的逻辑嵌套。
(内部)环境记录的外部引用是对逻辑上围绕内部环境记录的环境记录的引用。
外部环境记录当然可能有自己的外部环境记录。一个环境记录可以作为多个内部环境记录的外部环境。
例如,如果一个函数声明
包含两个嵌套的函数声明 ,
那么每个嵌套函数的环境记录都将以周围函数的当前求值的环境记录作为其外部环境记录。
环境记录纯粹是规范机制,不需要对应于ECMAScript实现的任何特定构件。
ECMAScript程序不可能直接访问或操作这样的值。
9.1.1 环境记录类型层次结构
环境记录 可以看作存在于一个简单的面向对象层次结构中,
其中环境记录 是一个
抽象类,有三个具体子类:声明式环境记录 、对象环境记录 和全局环境记录 。函数环境记录 和模块环境记录 是声明式环境记录 的子类。
环境记录 抽象类
包含表16 中定义的抽象规范方法。
这些抽象方法对于每个具体子类都有不同的具体算法。
表16:环境记录 的抽象方法
方法
目的
HasBinding(N)
确定环境记录
是否具有字符串值N 的绑定。如果有则返回
true ,如果没有则返回false 。
CreateMutableBinding(N, D)
在环境记录 中
创建一个新的但未初始化的可变绑定。
字符串值N 是绑定名称的文本。如果布尔参数D 是
true ,则绑定可以随后被删除。
CreateImmutableBinding(N, S)
在环境记录 中
创建一个新的但未初始化的不可变绑定。
字符串值N 是绑定名称的文本。如果S 是
true ,那么在初始化后尝试设置它时
总是会抛出异常,无论引用该绑定的操作的严格模式设置如何。
InitializeBinding(N, V)
设置环境记录 中
已存在但未初始化的绑定的值。
字符串值N 是绑定名称的文本。V 是
绑定的值,是任何ECMAScript语言类型 的值。
SetMutableBinding(N, V, S)
设置环境记录 中
已存在的可变绑定的值。
字符串值N 是绑定名称的文本。V 是
绑定的值,可能是任何ECMAScript语言类型 的值。S 是布尔值 标志。如果S 是
true 且绑定无法设置,则抛出
TypeError 异常。
GetBindingValue(N, S)
从环境记录 返回
已存在绑定的值。
字符串值N 是绑定名称的文本。S
用于标识源自严格模式代码 或
其他需要严格模式引用语义的引用。如果S 是
true 且绑定不存在,则抛出
ReferenceError 异常。如果绑定存在但未初始化,
则抛出ReferenceError ,无论S 的值如何。
DeleteBinding(N)
从环境记录 删除绑定。字符串值N 是
绑定名称的文本。如果N 的绑定存在,则移除绑定并
返回true 。如果绑定存在但无法移除,
则返回false 。如果绑定不存在,则返回
true 。
HasThisBinding()
确定环境记录
是否建立this绑定。如果建立则返回true ,
如果不建立则返回false 。
HasSuperBinding()
确定环境记录
是否建立super方法绑定。如果建立则返回
true ,如果不建立则返回false 。
如果返回true ,则暗示环境记录 是
函数环境记录 ,
但反向推导不成立。
WithBaseObject()
如果此环境记录 与
with语句关联,则返回with对象。
否则,返回undefined 。
9.1.1.1 声明式环境记录
每个声明式环境记录 都与包含变量、常量、let、类、模块、导入和/或函数声明的ECMAScript程序作用域相关联。声明式环境记录绑定其作用域内包含的声明所定义的标识符集合。
9.1.1.1.1 HasBinding ( N )
声明式环境记录
envRec 的HasBinding具体方法接受参数N
(字符串)并返回包含 布尔值的正常完成 。它确定参数标识符是否是记录绑定的标识符之一。调用时执行以下步骤:
如果envRec 具有N 的绑定,返回
true 。
返回false 。
9.1.1.1.2 CreateMutableBinding ( N , D
)
声明式环境记录
envRec 的CreateMutableBinding具体方法接受参数N (字符串)
和D (布尔值)并返回包含
unused 的正常完成 。它为名称N 创建一个新的未初始化的可变绑定。此环境记录 中不得已存在N 的绑定。如果D 是true ,则新绑定被标记为可删除的。调用时执行以下步骤:
断言 :
envRec 不已经具有N 的绑定。
在envRec 中为N 创建可变绑定并记录它是未初始化的。如果D 是true ,记录新创建的绑定可以被后续的DeleteBinding调用删除。
返回unused 。
9.1.1.1.3 CreateImmutableBinding ( N ,
S )
声明式环境记录
envRec 的CreateImmutableBinding具体方法接受参数N (字符串)
和S (布尔值)并返回包含
unused 的正常完成 。它为名称N 创建一个新的未初始化的不可变绑定。此环境记录 中不得已存在N 的绑定。如果S 是true ,则新绑定被标记为严格绑定。调用时执行以下步骤:
断言 :
envRec 不已经具有N 的绑定。
在envRec 中为N 创建不可变绑定并记录它是未初始化的。如果S 是true ,记录新创建的绑定是严格绑定。
返回unused 。
9.1.1.1.4 InitializeBinding ( N , V )
声明式环境记录
envRec 的InitializeBinding具体方法接受参数N (字符串)
和V (ECMAScript语言值 )
并返回包含
unused 的正常完成 。它用于将名称为N 的标识符的当前绑定的绑定值设置为值V 。N 的未初始化绑定必须已经存在。调用时执行以下步骤:
断言 :
envRec 必须具有N 的未初始化绑定。
将envRec 中N 的绑定值设置为V 。
记录 envRec 中N 的绑定已被初始化。
返回unused 。
9.1.1.1.5 SetMutableBinding ( N , V ,
S )
声明式环境记录
envRec 的SetMutableBinding具体方法接受参数N (字符串)、
V (ECMAScript语言值 )
和S (布尔值)并返回包含
unused 的正常完成 或抛出完成 。它尝试将名称为N 的标识符的当前绑定的绑定值更改为值V 。N 的绑定通常已经存在,但在罕见情况下可能不存在。如果绑定是不可变绑定,当S 是true 时抛出TypeError 。调用时执行以下步骤:
如果envRec 没有N 的绑定,则
如果S 是true ,抛出ReferenceError 异常。
执行! envRec .CreateMutableBinding(N ,
true )。
执行! envRec .InitializeBinding(N ,
V )。
返回unused 。
如果envRec 中N 的绑定是严格绑定,将S 设置为true 。
如果envRec 中N 的绑定尚未初始化,则
抛出ReferenceError 异常。
否则如果envRec 中N 的绑定是可变绑定,则
将其绑定值更改为V 。
否则,
断言 :这是尝试更改不可变绑定的值。
如果S 是true ,抛出TypeError 异常。
返回unused 。
注
导致步骤1 缺失绑定的ECMAScript代码示例是:
function f ( ) { eval ("var x; x = (delete x, 0);" ); }
9.1.1.1.6 GetBindingValue ( N , S )
声明式环境记录
envRec 的GetBindingValue具体方法接受参数N (字符串)
和S (布尔值)并返回包含 ECMAScript语言值 的正常完成 或抛出完成 。它返回名称为N 的绑定标识符的值。如果绑定存在但未初始化,则抛出ReferenceError ,无论S 的值如何。调用时执行以下步骤:
断言 :
envRec 具有N 的绑定。
如果envRec 中N 的绑定是未初始化绑定,抛出ReferenceError 异常。
返回envRec 中当前绑定到N 的值。
9.1.1.1.7 DeleteBinding ( N )
声明式环境记录
envRec 的DeleteBinding具体方法接受参数N (字符串)
并返回包含 布尔值的正常完成 。它只能删除已明确指定为可删除的绑定。调用时执行以下步骤:
断言 :
envRec 具有N 的绑定。
如果envRec 中N 的绑定无法删除,返回false 。
从envRec 中移除N 的绑定。
返回true 。
9.1.1.1.8 HasThisBinding ( )
声明式环境记录
envRec 的HasThisBinding具体方法不接受参数并返回false 。调用时执行以下步骤:
返回false 。
注
常规声明式环境记录 (即既不是函数环境记录 也不是模块环境记录 的记录)不提供this绑定。
9.1.1.1.9 HasSuperBinding ( )
声明式环境记录
envRec 的HasSuperBinding具体方法不接受参数并返回false 。调用时执行以下步骤:
返回false 。
注
常规声明式环境记录 (即既不是函数环境记录 也不是模块环境记录 的记录)不提供super绑定。
9.1.1.1.10 WithBaseObject ( )
声明式环境记录
envRec 的WithBaseObject具体方法不接受参数并返回undefined 。调用时执行以下步骤:
返回undefined 。
9.1.1.2 对象环境记录
每个对象环境记录
都与一个称为其绑定对象 的对象相关联。对象环境记录绑定一组字符串标识符名称,
这些名称直接对应于其绑定对象的属性名称。不是标识符名称 形式的字符串的属性键 不包含在绑定标识符集合中。无论其[[Enumerable]] 属性的设置如何,自有属性和继承属性都包含在集合中。由于属性可以动态地从对象中添加和删除,对象环境记录绑定的标识符集合可能会作为任何添加或删除属性操作的副作用而发生变化。作为这种副作用结果创建的任何绑定都被认为是可变绑定,即使相应属性的Writable属性是false 。对象环境记录不存在不可变绑定。
为with语句(14.11 )创建的对象环境记录可以提供其绑定对象作为函数调用中使用的隐式this 值。这种能力由布尔值[[IsWithEnvironment]] 字段控制。
对象环境记录具有表17 中列出的附加状态字段。
表17:对象环境记录 的附加字段
字段名称
值
含义
[[BindingObject]]
一个对象
此环境记录 的绑定对象。
[[IsWithEnvironment]]
布尔值
指示此环境记录 是否为with语句创建。
9.1.1.2.1 HasBinding ( N )
对象环境记录
envRec 的HasBinding具体方法接受参数N (字符串)
并返回包含 布尔值的正常完成 或抛出完成 。它确定其关联的绑定对象是否具有名称为N 的属性。调用时执行以下步骤:
设bindingObject 为envRec .[[BindingObject]] 。
设foundBinding 为? HasProperty (bindingObject ,
N )。
如果foundBinding 是false ,返回false 。
如果envRec .[[IsWithEnvironment]] 是false ,返回true 。
设unscopables 为? Get (bindingObject ,
%Symbol.unscopables% )。
如果unscopables 是对象 ,则
设blocked 为ToBoolean (? Get (unscopables ,
N ))。
如果blocked 是true ,返回false 。
返回true 。
9.1.1.2.2 CreateMutableBinding ( N , D
)
对象环境记录
envRec 的CreateMutableBinding具体方法接受参数N (字符串)和D (布尔值)
并返回包含
unused 的正常完成 或抛出完成 。它在环境记录 的关联绑定对象中创建一个名称为N 的属性,并将其初始化为值undefined 。如果D 是true ,新属性的[[Configurable]] 属性设置为true ;否则设置为false 。调用时执行以下步骤:
设bindingObject 为envRec .[[BindingObject]] 。
执行? DefinePropertyOrThrow (bindingObject ,
N , PropertyDescriptor { [[Value]] :
undefined , [[Writable]] :
true , [[Enumerable]] :
true , [[Configurable]] :
D })。
返回unused 。
注
通常envRec 不会有N 的绑定,但如果有,DefinePropertyOrThrow 的语义可能导致现有绑定被替换或遮蔽,或导致返回异常完成 。
9.1.1.2.3 CreateImmutableBinding ( N ,
S )
对象环境记录 的CreateImmutableBinding具体方法在本规范中从未使用。
9.1.1.2.4 InitializeBinding ( N , V )
对象环境记录
envRec 的InitializeBinding具体方法接受参数N (字符串)和V (ECMAScript语言值 )
并返回包含
unused 的正常完成 或抛出完成 。它用于将名称为N 的标识符的当前绑定的绑定值设置为值V 。调用时执行以下步骤:
执行? envRec .SetMutableBinding (N ,
V , false )。
返回unused 。
注
在本规范中,对对象环境记录 的CreateMutableBinding的所有使用之后都紧跟相同名称的InitializeBinding调用。因此,本规范不显式跟踪对象环境记录 中绑定的初始化状态。
9.1.1.2.5 SetMutableBinding ( N , V ,
S )
对象环境记录
envRec 的SetMutableBinding具体方法接受参数N (字符串)、V (ECMAScript语言值 )
和S (布尔值)并返回包含
unused 的正常完成 或抛出完成 。它尝试将环境记录 关联绑定对象的名称为N 的属性的值设置为值V 。名称为N 的属性通常已经存在,但如果不存在或当前不可写,错误处理由S 确定。调用时执行以下步骤:
设bindingObject 为envRec .[[BindingObject]] 。
设stillExists 为? HasProperty (bindingObject ,
N )。
如果stillExists 是false 且S 是true ,抛出ReferenceError 异常。
执行? Set (bindingObject ,
N , V , S )。
返回unused 。
9.1.1.2.6 GetBindingValue ( N , S )
对象环境记录
envRec 的GetBindingValue具体方法接受参数N (字符串)和S (布尔值)
并返回包含 ECMAScript语言值 的正常完成 或抛出完成 。它返回其关联绑定对象的名称为N 的属性的值。该属性应该已经存在,但如果不存在,结果取决于S 。调用时执行以下步骤:
设bindingObject 为envRec .[[BindingObject]] 。
设value 为? HasProperty (bindingObject ,
N )。
如果value 是false ,则
如果S 是false ,返回undefined ;否则抛出ReferenceError 异常。
返回? Get (bindingObject ,
N )。
9.1.1.2.7 DeleteBinding ( N )
对象环境记录
envRec 的DeleteBinding具体方法接受参数N (字符串)
并返回包含 布尔值的正常完成 或抛出完成 。它只能删除对应于环境对象的[[Configurable]] 属性值为true 的属性的绑定。调用时执行以下步骤:
设bindingObject 为envRec .[[BindingObject]] 。
返回? bindingObject .[[Delete]] (N )。
9.1.1.2.8 HasThisBinding ( )
对象环境记录
envRec 的HasThisBinding具体方法不接受参数并返回false 。调用时执行以下步骤:
返回false 。
注
9.1.1.2.9 HasSuperBinding ( )
对象环境记录
envRec 的HasSuperBinding具体方法不接受参数并返回false 。调用时执行以下步骤:
返回false 。
注
9.1.1.2.10 WithBaseObject ( )
对象环境记录
envRec 的WithBaseObject具体方法不接受参数并返回对象或undefined 。调用时执行以下步骤:
如果envRec .[[IsWithEnvironment]] 是true ,返回envRec .[[BindingObject]] 。
否则,返回undefined 。
9.1.1.3 函数环境记录
函数环境记录 是一个声明式环境记录 ,用于表示函数的顶层作用域,如果函数不是箭头函数 ,则提供this绑定。如果函数不是箭头函数 并且引用super,其函数环境记录还包含用于在函数内执行super方法调用的状态。
函数环境记录具有表18 中列出的附加状态字段。
表18:函数环境记录 的附加字段
字段名称
值
含义
[[ThisValue]]
一个ECMAScript语言值
这是用于此函数调用的this 值。
[[ThisBindingStatus]]
lexical 、initialized 或uninitialized
如果值是lexical ,这是一个箭头函数 ,不具有本地this 值。
[[FunctionObject]]
一个ECMAScript函数对象
调用导致创建此环境记录 的函数对象 。
[[NewTarget]]
一个构造函数 或undefined
如果此环境记录 由[[Construct]] 内部方法创建,[[NewTarget]] 是[[Construct]] 的newTarget 参数的值。否则,其值为undefined 。
函数环境记录支持表16 中列出的所有声明式环境记录 方法,除了HasThisBinding和HasSuperBinding,所有这些方法都共享相同的规范。此外,函数环境记录支持表19 中列出的方法:
表19:函数环境记录 的附加方法
方法
目的
GetThisBinding()
返回此环境记录 的this绑定的值。如果this绑定尚未初始化,则抛出ReferenceError 。
9.1.1.3.1 BindThisValue ( envRec , V )
抽象操作BindThisValue接受参数envRec (一个函数环境记录 )和V (一个ECMAScript语言值 )
并返回包含
unused 的正常完成 或抛出完成 。它设置envRec .[[ThisValue]] 并记录它已被初始化。调用时执行以下步骤:
断言 :
envRec .[[ThisBindingStatus]] 不是lexical 。
如果envRec .[[ThisBindingStatus]] 是initialized ,抛出ReferenceError 异常。
设置envRec .[[ThisValue]] 为V 。
设置envRec .[[ThisBindingStatus]] 为initialized 。
返回unused 。
9.1.1.3.2 HasThisBinding ( )
函数环境记录
envRec 的HasThisBinding具体方法不接受参数并返回布尔值。调用时执行以下步骤:
如果envRec .[[ThisBindingStatus]] 是lexical ,返回false ;否则,返回true 。
9.1.1.3.3 HasSuperBinding ( )
函数环境记录
envRec 的HasSuperBinding具体方法不接受参数并返回布尔值。调用时执行以下步骤:
如果envRec .[[ThisBindingStatus]] 是lexical ,返回false 。
如果envRec .[[FunctionObject]] .[[HomeObject]] 是undefined ,返回false ;否则,返回true 。
9.1.1.3.4 GetThisBinding ( )
函数环境记录
envRec 的GetThisBinding具体方法不接受参数并返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
断言 :
envRec .[[ThisBindingStatus]] 不是lexical 。
如果envRec .[[ThisBindingStatus]] 是uninitialized ,抛出ReferenceError 异常。
返回envRec .[[ThisValue]] 。
9.1.1.3.5 GetSuperBase ( envRec )
抽象操作GetSuperBase接受参数envRec (一个函数环境记录 )并返回对象、null 或undefined 。它返回作为envRec 中绑定的super属性访问基础的对象。值undefined 表示这种访问将产生运行时错误。调用时执行以下步骤:
设home 为envRec .[[FunctionObject]] .[[HomeObject]] 。
如果home 是undefined ,返回undefined 。
断言 :
home 是一个普通对象 。
返回! home .[[GetPrototypeOf]] ()。
9.1.1.4 全局环境记录
全局环境记录 用于表示被在共同领域 中处理的所有ECMAScript 脚本 元素所共享的最外层作用域。全局环境记录为内置全局变量(第19 章)、全局对象 的属性以及在脚本 中出现的所有顶级声明(8.2.9 ,
8.2.11 )提供绑定。
全局环境记录在逻辑上是单个记录,但它被指定为一个封装对象环境记录 和声明式环境记录 的复合体。对象环境记录 以关联领域记录 的全局对象 为基础对象。这个全局对象 是全局环境记录的GetThisBinding具体方法返回的值。全局环境记录的对象环境记录 组件包含所有内置全局变量的绑定(第19 章)以及由全局代码中的函数声明 、生成器声明 、
异步函数声明 、异步生成器声明 或变量语句 引入的所有绑定。全局代码中所有其他ECMAScript声明的绑定包含在全局环境记录的声明式环境记录 组件中。
属性可以直接在全局对象 上创建。因此,全局环境记录的对象环境记录 组件可能包含由函数声明 、生成器声明 、
异步函数声明 、异步生成器声明 或变量声明 声明显式创建的绑定和作为全局对象 属性隐式创建的绑定。为了识别哪些绑定是使用声明显式创建的,全局环境记录维护一个使用CreateGlobalVarBinding 和CreateGlobalFunctionBinding 抽象操作 绑定的名称列表。
全局环境记录具有表20 中列出的附加字段和表21 中列出的附加方法。
表20:全局环境记录 的附加字段
表21:全局环境记录 的附加方法
方法
目的
GetThisBinding()
返回此环境记录 的this绑定的值。
9.1.1.4.1 HasBinding ( N )
全局环境记录
envRec 的HasBinding具体方法接受参数N (字符串)
并返回包含 布尔值的正常完成 或抛出完成 。它确定参数标识符是否是记录绑定的标识符之一。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
返回true 。
设ObjRec 为envRec .[[ObjectRecord]] 。
返回? ObjRec .HasBinding (N )。
9.1.1.4.2 CreateMutableBinding ( N , D
)
全局环境记录
envRec 的CreateMutableBinding具体方法接受参数N (字符串)和D (布尔值)
并返回包含
unused 的正常完成 或抛出完成 。它为名称N 创建一个新的未初始化的可变绑定。绑定在关联的声明式记录中创建。声明式记录中不得已存在N 的绑定。如果D 是true ,则新绑定被标记为可删除的。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
抛出TypeError 异常。
返回! DclRec .CreateMutableBinding(N ,
D )。
9.1.1.4.3 CreateImmutableBinding ( N ,
S )
全局环境记录
envRec 的CreateImmutableBinding具体方法接受参数N (字符串)和S (布尔值)
并返回包含
unused 的正常完成 或抛出完成 。它为名称N 创建一个新的未初始化的不可变绑定。此环境记录 中不得已存在N 的绑定。如果S 是true ,则新绑定被标记为严格绑定。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
抛出TypeError 异常。
返回! DclRec .CreateImmutableBinding(N ,
S )。
9.1.1.4.4 InitializeBinding ( N , V )
全局环境记录
envRec 的InitializeBinding具体方法接受参数N (字符串)和V (ECMAScript语言值 )
并返回包含
unused 的正常完成 或抛出完成 。它用于将名称为N 的标识符的当前绑定的绑定值设置为值V 。N 的未初始化绑定必须已经存在。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
则
返回! DclRec .InitializeBinding(N ,
V )。
断言 :
如果绑定存在,它必须在对象环境记录 中。
设ObjRec 为envRec .[[ObjectRecord]] 。
返回? ObjRec .InitializeBinding (N ,
V )。
9.1.1.4.5 SetMutableBinding ( N , V ,
S )
全局环境记录
envRec 的SetMutableBinding具体方法接受参数N (字符串)、V (ECMAScript语言值 )
和S (布尔值)并返回包含
unused 的正常完成 或抛出完成 。它尝试将名称为N 的标识符的当前绑定的绑定值更改为值V 。如果绑定是不可变绑定且S 是true ,则抛出TypeError 。名称为N 的属性通常已经存在,但如果不存在或当前不可写,错误处理由S 确定。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
则
返回? DclRec .SetMutableBinding(N ,
V , S )。
设ObjRec 为envRec .[[ObjectRecord]] 。
返回? ObjRec .SetMutableBinding (N ,
V , S )。
9.1.1.4.6 GetBindingValue ( N , S )
全局环境记录
envRec 的GetBindingValue具体方法接受参数N (字符串)
和S (布尔值)并返回包含 ECMAScript语言值 的正常完成 或抛出完成 。它返回名称为N 的绑定标识符的值。如果绑定是未初始化绑定,则抛出ReferenceError 异常。名称为N 的属性通常已经存在,但如果不存在或当前不可写,错误处理由S 确定。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
则
返回? DclRec .GetBindingValue(N ,
S )。
设ObjRec 为envRec .[[ObjectRecord]] 。
返回? ObjRec .GetBindingValue (N ,
S )。
9.1.1.4.7 DeleteBinding ( N )
全局环境记录
envRec 的DeleteBinding具体方法接受参数N (字符串)
并返回包含 布尔值的正常完成 或抛出完成 。它只能删除已明确指定为可删除的绑定。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
如果! DclRec .HasBinding(N )是true ,
则
返回! DclRec .DeleteBinding(N )。
设ObjRec 为envRec .[[ObjectRecord]] 。
设globalObject 为ObjRec .[[BindingObject]] 。
设existingProp 为? HasOwnProperty (globalObject ,
N )。
如果existingProp 是true ,则
返回? ObjRec .DeleteBinding (N )。
返回true 。
9.1.1.4.8 HasThisBinding ( )
全局环境记录
envRec 的HasThisBinding具体方法不接受参数并返回true 。调用时执行以下步骤:
返回true 。
注
9.1.1.4.9 HasSuperBinding ( )
全局环境记录
envRec 的HasSuperBinding具体方法不接受参数并返回false 。调用时执行以下步骤:
返回false 。
注
9.1.1.4.10 WithBaseObject ( )
全局环境记录
envRec 的WithBaseObject具体方法不接受参数并返回undefined 。调用时执行以下步骤:
返回undefined 。
9.1.1.4.11 GetThisBinding ( )
全局环境记录
envRec 的GetThisBinding具体方法不接受参数并返回包含 对象的正常完成 。调用时执行以下步骤:
返回envRec .[[GlobalThisValue]] 。
9.1.1.4.12 HasLexicalDeclaration ( envRec ,
N )
抽象操作HasLexicalDeclaration接受参数envRec (一个全局环境记录 )
和N (字符串)并返回布尔值。它确定参数标识符是否在envRec 中有使用词法声明如词法声明 或类声明 创建的绑定。调用时执行以下步骤:
设DclRec 为envRec .[[DeclarativeRecord]] 。
返回! DclRec .HasBinding(N )。
9.1.1.4.13 HasRestrictedGlobalProperty ( envRec ,
N )
抽象操作HasRestrictedGlobalProperty接受参数envRec (一个全局环境记录 )
和N (字符串)并返回包含 布尔值的正常完成 或抛出完成 。它确定参数标识符是否是全局对象 的属性名称,该属性不得被全局词法绑定遮蔽。调用时执行以下步骤:
设ObjRec 为envRec .[[ObjectRecord]] 。
设globalObject 为ObjRec .[[BindingObject]] 。
设existingProp 为? globalObject .[[GetOwnProperty]] (N )。
如果existingProp 是undefined ,返回false 。
如果existingProp .[[Configurable]] 是true ,返回false 。
返回true 。
注
属性可能存在于全局对象 上,这些属性是直接创建的而不是使用var或函数声明声明的。不能创建与全局对象 的不可配置属性同名的全局词法绑定。全局属性"undefined" 就是这样一个属性的例子。
9.1.1.4.14 CanDeclareGlobalVar ( envRec ,
N )
抽象操作CanDeclareGlobalVar接受参数envRec (一个全局环境记录 )
和N (字符串)并返回包含 布尔值的正常完成 或抛出完成 。它确定如果为相同参数N 调用相应的CreateGlobalVarBinding 调用是否会成功。允许冗余的var声明和对预先存在的全局对象 属性的var声明。调用时执行以下步骤:
设ObjRec 为envRec .[[ObjectRecord]] 。
设globalObject 为ObjRec .[[BindingObject]] 。
设hasProperty 为? HasOwnProperty (globalObject ,
N )。
如果hasProperty 是true ,返回true 。
返回? IsExtensible (globalObject )。
9.1.1.4.15 CanDeclareGlobalFunction ( envRec ,
N )
抽象操作CanDeclareGlobalFunction接受参数envRec (一个全局环境记录 )
和N (字符串)并返回包含 布尔值的正常完成 或抛出完成 。它确定如果为相同参数N 调用相应的CreateGlobalFunctionBinding 调用是否会成功。调用时执行以下步骤:
设ObjRec 为envRec .[[ObjectRecord]] 。
设globalObject 为ObjRec .[[BindingObject]] 。
设existingProp 为? globalObject .[[GetOwnProperty]] (N )。
如果existingProp 是undefined ,返回? IsExtensible (globalObject )。
如果existingProp .[[Configurable]] 是true ,返回true 。
如果IsDataDescriptor (existingProp )
是true 且existingProp 有属性值{ [[Writable]] : true , [[Enumerable]] :
true },返回true 。
返回false 。
9.1.1.4.16 CreateGlobalVarBinding ( envRec ,
N , D )
抽象操作CreateGlobalVarBinding接受参数envRec (一个全局环境记录 )、N (字符串)和D (布尔值)
并返回包含
unused 的正常完成 或抛出完成 。它在关联的对象环境记录 中创建并初始化可变绑定。如果绑定已经存在,则重用它并假定已初始化。调用时执行以下步骤:
设ObjRec 为envRec .[[ObjectRecord]] 。
设globalObject 为ObjRec .[[BindingObject]] 。
设hasProperty 为? HasOwnProperty (globalObject ,
N )。
设extensible 为? IsExtensible (globalObject )。
如果hasProperty 是false 且extensible 是true ,则
执行? ObjRec .CreateMutableBinding (N ,
D )。
执行? ObjRec .InitializeBinding (N ,
undefined )。
返回unused 。
9.1.1.4.17 CreateGlobalFunctionBinding ( envRec ,
N , V , D )
抽象操作CreateGlobalFunctionBinding接受参数envRec (一个全局环境记录 )、N (字符串)、V (ECMAScript语言值 )
和D (布尔值)并返回包含
unused 的正常完成 或抛出完成 。它在关联的对象环境记录 中创建并初始化可变绑定。如果绑定已经存在,则替换它。调用时执行以下步骤:
设ObjRec 为envRec .[[ObjectRecord]] 。
设globalObject 为ObjRec .[[BindingObject]] 。
设existingProp 为? globalObject .[[GetOwnProperty]] (N )。
如果existingProp 是undefined 或existingProp .[[Configurable]] 是true ,则
设desc 为属性描述符{ [[Value]] :
V , [[Writable]] :
true , [[Enumerable]] :
true , [[Configurable]] :
D }。
否则,
设desc 为属性描述符{ [[Value]] :
V }。
执行? DefinePropertyOrThrow (globalObject ,
N , desc )。
执行? Set (globalObject ,
N , V , false )。
返回unused 。
注
全局函数声明总是表示为全局对象 的自有属性。如果可能,现有的自有属性会被重新配置为具有标准的属性值集合。步骤7 等效于调用InitializeBinding具体方法所做的操作,如果globalObject 是代理,将产生相同的代理陷阱调用序列。
9.1.1.5 模块环境记录
模块环境记录 是一个
声明式环境记录 ,用于表示 ECMAScript
模块 的外部作用域。除了普通的可变和不可变绑定之外,模块环境记录还提供不可变的导入绑定,这些绑定提供对存在于另一个
环境记录 中的目标绑定的间接访问。
模块环境记录支持 声明式环境记录 在 表 16
中列出的所有方法,除了 GetBindingValue、DeleteBinding、HasThisBinding 和 GetThisBinding
之外,所有这些方法都共享相同的规范。此外,模块环境记录支持 表
22 中列出的方法:
表 22:模块环境记录 的附加方法
方法
目的
GetThisBinding()
返回此 环境记录 的
this 绑定的值。
9.1.1.5.1 GetBindingValue ( N , S )
模块环境记录 envRec 的
GetBindingValue 具体方法接收参数 N (一个字符串)和 S (一个布尔值),并返回 包含 ECMAScript 语言值 的正常完成或
抛出完成 。它返回名称为
N 的绑定标识符的值。但是,如果绑定是间接绑定,则返回目标绑定的值。如果绑定存在但未初始化,则抛出
ReferenceError 。调用时执行以下步骤:
断言 :
S 是 true 。
断言 :
envRec 有一个 N 的绑定。
如果 N 的绑定是间接绑定,那么
设 M 和 N2 为创建此 N 绑定时提供的间接值。
设 targetEnv 为 M .[[Environment]] 。
如果 targetEnv 是 empty ,抛出
ReferenceError 异常。
返回 ? targetEnv .GetBindingValue (N2 ,
true )。
如果 envRec 中 N 的绑定是未初始化的绑定,抛出
ReferenceError 异常。
返回 envRec 中当前绑定到 N 的值。
注
S 将始终为 true ,因为 模块 始终是 严格模式代码 。
9.1.1.5.2 DeleteBinding ( N )
模块环境记录 的 DeleteBinding
具体方法在本规范中从未使用。
注
模块环境记录 仅在严格代码中使用,并且早期错误 规则防止在严格代码中将 delete 操作符应用于会解析为
模块环境记录 绑定的
引用记录 。参见
13.5.1.1 。
9.1.1.5.3 HasThisBinding ( )
模块环境记录 envRec 的
HasThisBinding 具体方法不接收参数,返回 true 。调用时执行以下步骤:
返回 true 。
注
9.1.1.5.4 GetThisBinding ( )
模块环境记录 envRec 的
GetThisBinding 具体方法不接收参数,返回 包含
undefined 的正常完成。调用时执行以下步骤:
返回 undefined 。
9.1.1.5.5 CreateImportBinding ( envRec ,
N , M , N2 )
抽象操作 CreateImportBinding 接收参数 envRec (一个 模块环境记录 )、N (一个字符串)、M (一个
模块记录 )和
N2 (一个字符串),并返回 unused 。它为名称 N
创建一个新的已初始化的不可变间接绑定。envRec 中不能已经存在 N 的绑定。N2 是存在于
M 的 模块环境记录 中的绑定的名称。对新绑定值的访问将间接访问目标绑定的绑定值。调用时执行以下步骤:
断言 :
envRec 还没有 N 的绑定。
断言 :
当 M .[[Environment]] 被实例化时,它将有一个
N2 的直接绑定。
在 envRec 中为 N 创建一个不可变的间接绑定,该绑定引用 M 和
N2 作为其目标绑定,并记录该绑定已初始化。
返回 unused 。
9.1.2 环境记录操作
本规范中使用以下抽象操作 来操作环境记录 :
9.1.2.1 GetIdentifierReference ( env ,
name , strict )
抽象操作 GetIdentifierReference 接收参数 env (一个环境记录 或
null )、name (一个字符串)和 strict (一个布尔值),并返回包含 引用记录 的正常完成或抛出完成 。调用时执行以下步骤:
如果 env 是 null ,那么
返回引用记录
{ [[Base]] :
unresolvable , [[ReferencedName]] : name , [[Strict]] : strict , [[ThisValue]] : empty }。
设 exists 为 ? env .HasBinding (name )。
如果 exists 是 true ,那么
返回引用记录
{ [[Base]] :
env , [[ReferencedName]] :
name , [[Strict]] : strict ,
[[ThisValue]] : empty }。
否则,
设 outer 为 env .[[OuterEnv]] 。
返回 ? GetIdentifierReference (outer ,
name , strict )。
9.1.2.2 NewDeclarativeEnvironment ( E )
抽象操作 NewDeclarativeEnvironment 接收参数 E (一个环境记录 或
null ),并返回一个声明式环境记录 。调用时执行以下步骤:
设 env 为一个不包含绑定的新声明式环境记录 。
设置 env .[[OuterEnv]] 为 E 。
返回 env 。
9.1.2.3 NewObjectEnvironment ( O , W ,
E )
抽象操作 NewObjectEnvironment 接收参数 O (一个对象)、W (一个布尔值)和
E (一个环境记录 或
null ),并返回一个对象环境记录 。调用时执行以下步骤:
设 env 为一个新的对象环境记录 。
设置 env .[[BindingObject]] 为 O 。
设置 env .[[IsWithEnvironment]] 为 W 。
设置 env .[[OuterEnv]] 为 E 。
返回 env 。
9.1.2.4 NewFunctionEnvironment ( F ,
newTarget )
抽象操作 NewFunctionEnvironment 接收参数 F (一个 ECMAScript 函数对象 )和
newTarget (一个对象或 undefined ),并返回一个函数环境记录 。调用时执行以下步骤:
设 env 为一个不包含绑定的新函数环境记录 。
设置 env .[[FunctionObject]] 为 F 。
如果 F .[[ThisMode]] 是
lexical ,设置 env .[[ThisBindingStatus]] 为 lexical 。
否则,设置 env .[[ThisBindingStatus]] 为
uninitialized 。
设置 env .[[NewTarget]] 为 newTarget 。
设置 env .[[OuterEnv]] 为 F .[[Environment]] 。
返回 env 。
9.1.2.5 NewGlobalEnvironment ( G ,
thisValue )
抽象操作 NewGlobalEnvironment 接收参数 G (一个对象)和 thisValue (一个对象),并返回一个全局环境记录 。调用时执行以下步骤:
设 objRec 为 NewObjectEnvironment (G ,
false , null )。
设 dclRec 为 NewDeclarativeEnvironment (null )。
设 env 为一个新的全局环境记录 。
设置 env .[[ObjectRecord]] 为 objRec 。
设置 env .[[GlobalThisValue]] 为
thisValue 。
设置 env .[[DeclarativeRecord]] 为
dclRec 。
设置 env .[[OuterEnv]] 为 null 。
返回 env 。
9.1.2.6 NewModuleEnvironment ( E )
抽象操作 NewModuleEnvironment 接收参数 E (一个环境记录 ),并返回一个模块环境记录 。调用时执行以下步骤:
设 env 为一个不包含绑定的新模块环境记录 。
设置 env .[[OuterEnv]] 为 E 。
返回 env 。
9.2 私有环境记录
私有环境记录 是一种规范机制,用于基于 ECMAScript 代码中 类声明 和 类表达式 的词法嵌套结构来跟踪私有名称 。它们类似于但区别于环境记录 。每个私有环境记录 都与一个 类声明 或 类表达式 关联。每次求值这样的类时,都会创建一个新的私有环境记录 来记录该类声明的私有名称 。
每个私有环境记录 都具有表 23 中定义的字段。
表 23:私有环境记录 字段
9.2.1 私有环境记录操作
本规范中使用以下抽象操作 来操作私有环境记录 :
9.2.1.1 NewPrivateEnvironment ( outerPrivateEnv )
抽象操作 NewPrivateEnvironment 接收参数 outerPrivateEnv (一个私有环境记录 或
null ),并返回一个私有环境记录 。调用时执行以下步骤:
设 names 为一个新的空列表 。
返回私有环境记录 {
[[OuterPrivateEnvironment]] : outerPrivateEnv ,
[[Names]] : names }。
9.2.1.2 ResolvePrivateIdentifier ( privateEnv ,
identifier )
抽象操作 ResolvePrivateIdentifier 接收参数 privateEnv (一个私有环境记录 )和
identifier (一个字符串),并返回一个私有名称 。调用时执行以下步骤:
设 names 为 privateEnv .[[Names]] 。
对于 names 的每个私有名称 pn ,执行
如果 pn .[[Description]] 是
identifier ,那么
返回 pn 。
设 outerPrivateEnv 为 privateEnv .[[OuterPrivateEnvironment]] 。
断言 :
outerPrivateEnv 不是 null 。
返回 ResolvePrivateIdentifier (outerPrivateEnv ,
identifier )。
9.3 领域
在求值之前,所有 ECMAScript 代码都必须与一个领域 关联。从概念上讲,一个领域 由一组内建对象、一个 ECMAScript 全局环境、在该全局环境作用域内加载的所有 ECMAScript
代码以及其他关联的状态和资源组成。
在本规范中,领域 表示为具有表
24 中指定字段的领域记录 :
表 24:领域记录 字段
9.3.1 InitializeHostDefinedRealm ( )
抽象操作 InitializeHostDefinedRealm 不接收参数,并返回包含
unused 的正常完成或抛出完成 。调用时执行以下步骤:
设 realm 为一个新的领域记录 。
执行 CreateIntrinsics (realm )。
设置 realm .[[AgentSignifier]] 为 AgentSignifier ()。
设置 realm .[[TemplateMap]] 为一个新的空列表 。
设 newContext 为一个新的执行上下文 。
设置 newContext 的 Function 为 null 。
设置 newContext 的领域 为 realm 。
设置 newContext 的 ScriptOrModule 为 null 。
将 newContext 推入执行上下文栈 ;newContext
现在是运行执行上下文 。
如果宿主 要求使用异质对象 作为
realm 的全局对象 ,那么
设 global 为以宿主定义 的方式创建的这样一个对象。
否则,
设 global 为 OrdinaryObjectCreate (realm .[[Intrinsics]] .[[%Object.prototype% ]])。
如果宿主 要求
realm 的全局作用域中的 this 绑定返回除全局对象 之外的对象,那么
设 thisValue 为以宿主定义 的方式创建的这样一个对象。
否则,
设 thisValue 为 global 。
设置 realm .[[GlobalObject]] 为 global 。
设置 realm .[[GlobalEnv]] 为 NewGlobalEnvironment (global ,
thisValue )。
执行 ? SetDefaultGlobalBindings (realm )。
在 global 上创建任何宿主定义 的全局对象 属性。
返回 unused 。
9.3.2 CreateIntrinsics ( realmRec )
抽象操作 CreateIntrinsics 接收参数 realmRec (一个领域记录 ),并返回 unused 。调用时执行以下步骤:
设置 realmRec .[[Intrinsics]] 为一个新的记录 。
使用表 6 中列出的值设置
realmRec .[[Intrinsics]]
的字段。字段名称是表第一列中列出的名称。每个字段的值是一个新的对象值,完全且递归地填充了属性值,如子句19 到28 中每个对象的规范所定义。所有对象属性值都是新创建的对象值。所有作为内建函数对象 的值都通过执行 CreateBuiltinFunction (steps ,
length , name , slots , realmRec ,
prototype ) 创建,其中 steps 是本规范提供的该函数的定义,name 是函数
"name" 属性的初始值,length 是函数 "length"
属性的初始值,slots 是函数指定的内部插槽名称的列表(如果有),prototype 是函数 [[Prototype]] 内部插槽的指定值。内建对象及其属性的创建必须有序,以避免依赖尚未创建的对象。
执行 AddRestrictedFunctionProperties (realmRec .[[Intrinsics]] .[[%Function.prototype% ]],
realmRec )。
返回 unused 。
9.3.3 SetDefaultGlobalBindings ( realmRec )
抽象操作 SetDefaultGlobalBindings 接收参数 realmRec (一个领域记录 ),并返回包含
unused 的正常完成或抛出完成 。调用时执行以下步骤:
设 global 为 realmRec .[[GlobalObject]] 。
对于子句19 中指定的全局对象的每个属性,执行
设 name 为属性名称 的字符串值。
设 desc 为该属性的完全填充的数据属性描述符 ,包含该属性的指定特性。对于19.2 、19.3 或19.4 中列出的属性,[[Value]] 特性的值是来自 realmRec 的相应内建对象。
执行 ? DefinePropertyOrThrow (global ,
name , desc )。
返回 unused 。
9.4 执行上下文
执行上下文 是一种规范设备,用于跟踪 ECMAScript
实现对代码的运行时求值。在任何时候,每个代理 最多有一个实际在执行代码的执行上下文。这被称为代理 的运行执行上下文 。本规范中对运行执行上下文 的所有引用都指周围代理 的运行执行上下文 。
执行上下文栈 用于跟踪执行上下文。运行执行上下文 始终是该栈的顶部元素。每当控制从与当前运行执行上下文 关联的可执行代码转移到与该执行上下文不关联的可执行代码时,就会创建一个新的执行上下文。新创建的执行上下文被推入栈中并成为运行执行上下文 。
执行上下文包含跟踪其关联代码的执行进度所需的任何实现特定状态。每个执行上下文至少具有表 25 中列出的状态组件。
表 25:所有执行上下文的状态组件
运行执行上下文 对代码的求值 可能在本规范内定义的各个点被暂停。一旦运行执行上下文 被暂停,不同的执行上下文可能成为运行执行上下文 并开始求值其代码。在稍后的某个时间,被暂停的执行上下文可能再次成为运行执行上下文 并在之前被暂停的点继续求值其代码。运行执行上下文 状态在执行上下文间的转换通常以类似栈的后进先出方式发生。然而,某些
ECMAScript 特性需要运行执行上下文 的非 LIFO 转换。
运行执行上下文 的领域 组件的值也被称为当前领域记录 。运行执行上下文 的 Function 组件的值也被称为活动函数对象 。
ECMAScript 代码执行上下文 具有表
26 中列出的附加状态组件。
表 26:ECMAScript 代码执行上下文的附加状态组件
执行上下文的 LexicalEnvironment 和 VariableEnvironment 组件始终是环境记录 。
表示生成器求值的执行上下文具有表
27 中列出的附加状态组件。
表 27:生成器执行上下文的附加状态组件
组件
目的
Generator
此执行上下文 正在求值的生成器。
在大多数情况下,只有运行执行上下文 (执行上下文栈 的顶部)被本规范内的算法直接操作。因此,当使用术语"LexicalEnvironment"和"VariableEnvironment"而不加限定时,它们指的是运行执行上下文 的这些组件。
执行上下文纯粹是一种规范机制,不需要对应 ECMAScript 实现的任何特定工件。ECMAScript 代码不可能直接访问或观察执行上下文。
9.4.1 GetActiveScriptOrModule ( )
抽象操作 GetActiveScriptOrModule 不接收参数,并返回脚本记录 、模块记录 或
null 。它用于基于运行执行上下文 确定运行的脚本或模块。调用时执行以下步骤:
如果执行上下文栈 为空,返回
null 。
设 ec 为执行上下文栈 上 ScriptOrModule 组件不为
null 的最顶层执行上下文 。
如果不存在这样的执行上下文 ,返回
null 。否则,返回 ec 的 ScriptOrModule。
9.4.2 ResolveBinding ( name [ , env ] )
抽象操作 ResolveBinding 接收参数 name (一个字符串)和可选参数 env (一个环境记录 或
undefined ),并返回包含 引用记录 的正常完成或抛出完成 。它用于确定
name 的绑定。env 可用于显式提供要搜索绑定的环境记录 。调用时执行以下步骤:
如果 env 不存在或 env 是 undefined ,那么
设置 env 为运行执行上下文 的
LexicalEnvironment。
断言 :
env 是一个环境记录 。
设 strict 为 IsStrict (正在求值的语法产生式)。
返回 ? GetIdentifierReference (env ,
name , strict )。
注
ResolveBinding 的结果始终是一个引用记录 ,其 [[ReferencedName]] 字段为 name 。
9.4.3 GetThisEnvironment ( )
抽象操作 GetThisEnvironment 不接收参数,并返回一个环境记录 。它找到当前提供关键字 this
绑定的环境记录 。调用时执行以下步骤:
设 env 为运行执行上下文 的 LexicalEnvironment。
重复,
设 exists 为 env .HasThisBinding()。
如果 exists 是 true ,返回 env 。
设 outer 为 env .[[OuterEnv]] 。
断言 :
outer 不是 null 。
设置 env 为 outer 。
注
步骤2 中的循环将始终终止,因为环境列表总是以具有
this 绑定的全局环境结束。
9.4.5 ResolveThisBinding ( )
抽象操作 ResolveThisBinding 不接收参数,并返回包含 ECMAScript 语言值 的正常完成或抛出完成 。它使用运行执行上下文 的 LexicalEnvironment 确定关键字 this
的绑定。调用时执行以下步骤:
设 envRec 为 GetThisEnvironment ()。
返回 ? envRec .GetThisBinding()。
9.4.5 GetNewTarget ( )
抽象操作 GetNewTarget 不接收参数,并返回一个对象或 undefined 。它使用运行执行上下文 的 LexicalEnvironment 确定
NewTarget 值。调用时执行以下步骤:
设 envRec 为 GetThisEnvironment ()。
断言 :
envRec 有一个 [[NewTarget]] 字段。
返回 envRec .[[NewTarget]] 。
9.4.6 GetGlobalObject ( )
抽象操作 GetGlobalObject 不接收参数,并返回一个对象。它返回当前运行执行上下文 使用的全局对象 。调用时执行以下步骤:
设 currentRealm 为当前领域记录 。
返回 currentRealm .[[GlobalObject]] 。
9.5 作业和宿主操作入队作业
作业 是一个无参数的抽象闭包 ,当没有其他 ECMAScript 计算正在进行时,它启动
ECMAScript 计算。
作业 由特定代理 中的 ECMAScript 宿主环境 调度执行。本规范描述了宿主钩子 HostEnqueueGenericJob 、HostEnqueueFinalizationRegistryCleanupJob 、HostEnqueuePromiseJob 和HostEnqueueTimeoutJob 来调度作业。本规范中的宿主钩子 按对作业调度施加的附加约束进行组织。宿主 可以定义调度作业的附加抽象操作 。这些操作接受作业 抽象闭包 和领域 (一个领域记录 或null )作为参数。如果提供了领域记录 ,这些操作调度作业在将来某个时间在提供的领域 中执行,在拥有该领域 的代理 中。如果为领域 提供null ,则作业不会求值 ECMAScript
代码。它们的实现必须符合以下要求:
注 1
宿主环境 不需要在调度方面统一对待
作业 。例如,Web 浏览器和 Node.js 将 Promise 处理
作业 视为比其他工作更高的优先级;未来的特性可能添加不被视为如此高优先级的
作业 。
在任何特定时间,scriptOrModule (一个脚本记录 、一个模块记录 或null )是活动脚本或模块 ,如果所有以下条件都为真:
在任何特定时间,如果所有以下条件都为真,则执行准备求值 ECMAScript 代码 :
注 2
宿主环境 可以通过将执行上下文 推入执行上下文栈 来准备执行求值代码。具体步骤是实现定义 的。
领域 的具体选择取决于宿主环境 。这个初始执行上下文 和领域 仅在调用任何回调函数之前使用。当调用与作业 相关的回调函数(如 Promise
处理程序)时,调用会推入自己的执行上下文 和领域 。
特定类型的作业 有附加的一致性要求。
9.5.1 作业回调记录
作业回调记录 是用于存储函数对象 和宿主定义 值的记录 值。通过宿主 入队的作业 调用的函数对象 可能有附加的宿主定义 上下文。为了传播状态,作业 抽象闭包 不应该直接捕获和调用函数对象 。相反,使用HostMakeJobCallback 和HostCallJobCallback 。
注
例如,WHATWG HTML 规范(https://html.spec.whatwg.org/ )使用宿主定义 值来为
Promise 回调传播现任设置对象。
作业回调记录具有表 28 中列出的字段。
表 28:作业回调记录 字段
字段名称
值
含义
[[Callback]]
一个函数对象
调用作业 时要调用的函数。
[[HostDefined]]
任何值(默认值为empty )
为宿主 保留使用的字段。
9.5.2 HostMakeJobCallback ( callback )
宿主定义 的抽象操作
HostMakeJobCallback 接收参数 callback (一个函数对象 ),并返回一个作业回调记录 。
HostMakeJobCallback 的实现必须符合以下要求:
它必须返回一个作业回调记录 ,其[[Callback]] 字段为callback 。
HostMakeJobCallback 的默认实现在调用时执行以下步骤:
返回作业回调记录 { [[Callback]] : callback , [[HostDefined]] : empty }。
非 Web 浏览器的 ECMAScript 宿主 必须使用
HostMakeJobCallback 的默认实现。
注
这在回调被传递给负责其最终调度和运行的函数时调用。例如,promise.then(thenAction) 在调用
Promise.prototype.then 时对 thenAction 调用
MakeJobCallback,而不是在调度反应作业 时。
9.5.3 HostCallJobCallback ( jobCallback , V ,
argumentsList )
宿主定义 的抽象操作
HostCallJobCallback 接收参数 jobCallback (一个作业回调记录 )、V (一个ECMAScript 语言值 )和
argumentsList (ECMAScript 语言值 的列表 ),并返回包含 ECMAScript 语言值 的正常完成或抛出完成 。
HostCallJobCallback 的实现必须符合以下要求:
它必须执行并返回Call (jobCallback .[[Callback]] , V , argumentsList )的结果。
注
这个要求意味着宿主 不能改变本规范中定义的函数对象 的[[Call]] 行为。
HostCallJobCallback 的默认实现在调用时执行以下步骤:
断言 :
IsCallable (jobCallback .[[Callback]] ) 是true 。
返回 ? Call (jobCallback .[[Callback]] , V , argumentsList )。
非 Web 浏览器的 ECMAScript 宿主 必须使用
HostCallJobCallback 的默认实现。
9.5.4 HostEnqueueGenericJob ( job , realm )
宿主定义 的抽象操作
HostEnqueueGenericJob 接收参数 job (一个作业 抽象闭包 )和realm (一个领域记录 ),并返回unused 。它在由realm .[[AgentSignifier]] 表示的代理 中的领域 realm
中调度job 在将来某个时间执行。与此算法一起使用的抽象闭包 旨在无附加约束(如优先级和排序)地调度。
HostEnqueueGenericJob 的实现必须符合9.5 中的要求。
9.5.5 HostEnqueuePromiseJob ( job , realm )
宿主定义 的抽象操作
HostEnqueuePromiseJob 接收参数 job (一个作业 抽象闭包 )和realm (一个领域记录 或null ),并返回unused 。它调度job 在将来某个时间执行。与此算法一起使用的抽象闭包 旨在与 Promise 处理相关,或者以与 Promise
处理操作相等的优先级调度。
HostEnqueuePromiseJob 的实现必须符合9.5 中的要求以及以下要求:
注
NewPromiseResolveThenableJob 返回的作业 的realm 通常是在then 函数对象 上调用GetFunctionRealm 的结果。NewPromiseReactionJob 返回的作业 的realm 通常是在处理程序不是undefined 时在处理程序上调用GetFunctionRealm 的结果。如果处理程序是undefined ,则realm 为null 。对于两种类型的作业 ,当GetFunctionRealm 异常完成(即在被撤销的代理上调用)时,realm 是GetFunctionRealm 调用时的当前领域记录 。当realm 为null 时,不会求值用户
ECMAScript 代码,也不会创建新的 ECMAScript 对象(例如错误对象)。例如,WHATWG HTML 规范(https://html.spec.whatwg.org/ )使用realm 来检查运行脚本的能力和入口 概念。
9.5.6 HostEnqueueTimeoutJob ( timeoutJob ,
realm , milliseconds )
宿主定义 的抽象操作
HostEnqueueTimeoutJob 接收参数 timeoutJob (一个作业 抽象闭包 )、realm (一个领域记录 )和milliseconds (一个非负有限 数字),并返回unused 。它在由realm .[[AgentSignifier]] 表示的代理 中的领域 realm
中调度timeoutJob 在至少milliseconds 毫秒后执行。
HostEnqueueTimeoutJob 的实现必须符合9.5 中的要求。
9.6 代理
代理 包含一组 ECMAScript 执行上下文 、一个执行上下文栈 、一个运行执行上下文 、一个代理记录 和一个执行线程 。除了执行线程 之外,代理 的组成部分专属于该代理 。
代理 的执行线程 在该代理 的执行上下文 上独立于其他代理 执行算法步骤,但是一个执行线程 可以被多个代理 用作执行线程 ,只要共享该线程的代理 都没有[[CanBlock]] 字段为true 的代理记录 。
注 1
例如,一些 Web 浏览器在浏览器窗口的多个不相关选项卡之间共享单个执行线程 。
当代理 的执行线程 正在执行算法步骤时,该代理 是那些步骤的周围代理 。这些步骤使用周围代理 来访问在该代理 内持有的规范级执行对象:运行执行上下文 、执行上下文栈 和代理记录 的字段。
代理标识符 是用于标识代理 的全局唯一不透明值。
表 29:代理记录 字段
字段名称
值
含义
[[LittleEndian]]
布尔值
当算法GetValueFromBuffer 和SetValueInBuffer 需要时为isLittleEndian 参数计算的默认值。选择是实现定义 的,应该是对实现最有效的选择。一旦该值被观察到,它就不能改变。
[[CanBlock]]
布尔值
确定代理 是否可以阻塞。
[[Signifier]]
一个代理标识符
在其代理集群 内唯一标识代理 。
[[IsLockFree1]]
布尔值
如果对单字节值的原子操作是无锁的,则为true ,否则为false 。
[[IsLockFree2]]
布尔值
如果对双字节值的原子操作是无锁的,则为true ,否则为false 。
[[IsLockFree8]]
布尔值
如果对八字节值的原子操作是无锁的,则为true ,否则为false 。
[[CandidateExecution]]
一个候选执行 记录
参见内存模型 。
[[KeptAlive]]
对象或符号的列表
初始为一个新的空列表 ,表示要保持活跃直到当前作业 结束的对象和/或符号列表。
[[ModuleAsyncEvaluationCount]]
一个整数
初始为 0,用于为异步或具有异步依赖的模块的[[AsyncEvaluationOrder]] 字段分配唯一的递增值。
一旦[[Signifier]] 、[[IsLockFree1]] 和[[IsLockFree2]] 的值被代理集群 中的任何代理 观察到,它们就不能改变。
注 2
[[IsLockFree1]] 和[[IsLockFree2]] 的值不一定由硬件决定,也可能反映可能随时间和 ECMAScript 实现而变化的实现选择。
没有[[IsLockFree4]] 字段:4 字节原子操作总是无锁的。
实际上,如果原子操作是用任何类型的锁实现的,则该操作不是无锁的。无锁并不意味着无等待:对于完成无锁原子操作可能需要多少个机器步骤没有上限。
大小为n 的原子访问是无锁的,并不意味着大小为n 的非原子访问的(感知的)原子性,具体来说,非原子访问仍然可能作为几个单独的内存访问序列来执行。详见ReadSharedMemory 和WriteSharedMemory 。
注 3
代理 是一种规范机制,不需要对应
ECMAScript 实现的任何特定工件。
9.6.1 AgentSignifier ( )
抽象操作 AgentSignifier 不接收参数,并返回一个代理标识符 。调用时执行以下步骤:
设AR 为周围代理 的代理记录 。
返回AR .[[Signifier]] 。
9.6.2 AgentCanSuspend ( )
抽象操作 AgentCanSuspend 不接收参数,并返回一个布尔值。调用时执行以下步骤:
设AR 为周围代理 的代理记录 。
返回AR .[[CanBlock]] 。
注
在某些环境中,给定代理 暂停可能不合理。例如,在 Web
浏览器环境中,禁止暂停文档的主事件处理线程可能是合理的,而仍然允许工作线程的事件处理线程暂停。
9.6.3 IncrementModuleAsyncEvaluationCount ( )
抽象操作 IncrementModuleAsyncEvaluationCount 不接收参数,并返回一个整数 。调用时执行以下步骤:
设AR 为周围代理 的代理记录 。
设count 为AR .[[ModuleAsyncEvaluationCount]] 。
设置AR .[[ModuleAsyncEvaluationCount]] 为count
+ 1。
返回count 。
注
此值仅用于跟踪挂起模块之间的相对求值顺序。当没有挂起模块时,实现可以不可观察地将[[ModuleAsyncEvaluationCount]] 重置为 0。
9.7 代理集群
代理集群 是可以通过操作共享内存进行通信的代理 的最大集合。
注 1
不同代理 内的程序可以通过未指定的方式共享内存。至少,SharedArrayBuffers
的后备内存可以在集群中的代理 之间共享。
可能存在可以通过消息传递进行通信但不能共享内存的代理 ;它们永远不在同一个代理集群中。
每个代理 都恰好属于一个代理集群。
注 2
集群中的代理 不需要在某个特定时间点都处于活跃状态。如果代理 A 创建另一个代理 B ,之后 A 终止且 B
创建代理 C ,如果
A 可以与 B 共享一些内存且 B 可以与 C 共享一些内存,则这三个代理 在同一个集群中。
集群内的所有代理 在其各自代理记录 中的[[LittleEndian]] 字段必须具有相同的值。
注 3
如果代理集群内不同的代理 具有不同的[[LittleEndian]] 值,则很难将共享内存用于多字节数据。
集群内的所有代理 在其各自代理记录 中的[[IsLockFree1]] 字段必须具有相同的值;[[IsLockFree2]] 字段也是如此。
集群内的所有代理 在其各自代理记录 中的[[Signifier]] 字段必须具有不同的值。
嵌入可以在代理 不知情或不配合的情况下停用(停止前进进度)或激活(恢复前进进度)代理 。如果嵌入这样做,它不得让集群中的某些代理 保持活跃状态,而集群中的其他代理 被无限期地停用。
注 4
前述限制的目的是避免代理 因为另一个代理 被停用而死锁或饥饿的情况。例如,如果具有独立于任何窗口中文档的生命周期的 HTML
共享工作线程被允许与这种独立文档的专用工作线程共享内存,并且文档及其专用工作线程在专用工作线程持有锁时被停用(例如,文档被推入其窗口的历史记录),然后共享工作线程尝试获取锁,那么共享工作线程将被阻塞,直到专用工作线程再次被激活(如果有的话)。与此同时,试图从其他窗口访问共享工作线程的其他工作线程将饥饿。
此限制的含义是,不属于嵌入中同一暂停/唤醒集合的代理 之间将无法共享内存。
嵌入可以在代理 集群的其他代理 事先不知情或不配合的情况下终止代理 。如果代理 不是通过自身或集群中另一个代理 的程序动作终止,而是被集群外部的力量终止,那么嵌入必须选择两种策略之一:要么终止集群中的所有代理 ,要么提供可靠的 API,允许集群中的代理 进行协调,使得集群的至少一个剩余成员能够检测到终止,终止数据包含足够的信息来标识被终止的代理 。
注 5
这种类型的终止的例子包括:操作系统或用户终止在单独进程中运行的代理 ;嵌入本身终止与其他代理 在同一进程中运行的代理 ,当按代理 的资源计算表明该代理 失控时。
以下每个规范值以及从它们可传递到达的值都恰好属于一个代理集群。
在集群中任何代理 对任何 ECMAScript
代码进行任何求值之前,集群中所有代理 的代理记录 的[[CandidateExecution]] 字段被设置为初始候选执行 。初始候选执行 是一个空候选执行 ,其[[EventsRecords]] 字段是一个列表 ,为每个代理 包含一个代理事件记录 ,其[[AgentSignifier]] 字段是该代理 的代理标识符 ,并且其[[EventList]] 和[[AgentSynchronizesWith]] 字段是空的列表 。
注 6
代理集群中的所有代理 在其代理记录 的[[CandidateExecution]] 字段中共享相同的候选执行 。候选执行 是内存模型 使用的规范机制。
注 7
代理集群是一种规范机制,不需要对应 ECMAScript 实现的任何特定工件。
9.8 前进进度
代理 取得前进进度 是指其根据本规范执行求值步骤。
当代理 的运行执行上下文 同步且无限期地等待外部事件时,该代理变为阻塞 状态。只有代理记录 的[[CanBlock]] 字段为true 的代理 才能在这种意义上变为阻塞状态。非阻塞 的代理 是指不处于阻塞状态的代理。
实现必须确保:
注
这与内存模型 中的活跃性保证一起,确保所有seq-cst 写入最终对所有代理 变为可观察的。
9.9 WeakRef 和 FinalizationRegistry 目标的处理模型
9.9.1 目标
本规范不保证任何对象或符号会被垃圾回收。不活跃 的对象或符号可能在很长时间后被释放,或者永远不被释放。因此,本规范在描述由垃圾回收触发的行为时使用"可能"一词。
WeakRefs 和FinalizationRegistrys 的语义基于在特定时间点发生的两个操作:
这两个动作(ClearKeptObjects 或CleanupFinalizationRegistry )都不能中断同步
ECMAScript 执行。因为宿主 可能组装更长的同步
ECMAScript 执行运行,本规范将ClearKeptObjects 和CleanupFinalizationRegistry 的调度推迟到宿主环境 。
一些 ECMAScript 实现包括在后台运行的垃圾收集器实现,包括当 ECMAScript 处于空闲状态时。让宿主环境 调度CleanupFinalizationRegistry 允许它恢复
ECMAScript 执行以运行终结器工作,这可能释放持有的值,减少整体内存使用。
9.9.2 活跃性
对于某个对象和/或符号集合S ,关于S 的假设 WeakRef
无关 执行是指这样的执行:其引用对象是S 元素的WeakRef 的抽象操作WeakRefDeref 总是返回undefined 。
注 1
WeakRef 无关性与活跃性一起捕获两个概念。一是
WeakRef 本身不会使其引用对象保持活跃。二是活跃性中的循环并不意味着值是活跃的。具体来说,如果确定
v 的活跃性依赖于确定
WeakRef 引用对象
r 的活跃性,则
r 的活跃性不能假设
v 的活跃性,这将是循环推理。
注 2
WeakRef 无关性是在对象或符号集合上定义的,而不是在单个值上定义的,以考虑循环。如果它是在单个值上定义的,那么循环中的
WeakRef 引用对象将被认为是活跃的,即使其身份只能通过循环中的其他
WeakRef 引用对象观察到。
注 3
通俗地说,如果包含单个对象或符号的每个集合都是活跃的,我们就说该对象或符号是活跃的。
在求值期间的任何时点,如果满足以下任一条件,则对象和/或符号集合S 被认为是活跃的 :
S 中的任何元素都包含在任何代理 的[[KeptAlive]] 列表 中。
存在一个关于S 的有效未来假设 WeakRef 无关执行,该执行观察S 中任何值的身份。
注 4
上述第二个条件旨在捕获这样的直觉:如果值的身份可以通过非
WeakRef 方式观察到,则该值是活跃的。值的身份可以通过观察严格相等比较或观察值被用作
Map 中的键来观察。
注 5
对象或符号在字段、内部槽或属性中的存在并不意味着该值是活跃的。例如,如果所讨论的值从未传回程序,那么它就无法被观察到。
WeakMap 中的键、WeakSet 的成员以及FinalizationRegistry 单元记录的[[WeakRefTarget]] 和[[UnregisterToken]] 字段都是这种情况。
上述定义意味着,如果 WeakMap 中的键不是活跃的,那么其对应的值也不一定是活跃的。
注 6
活跃性是保证引擎不得清空哪些
WeakRefs 的下界。这里定义的活跃性是不可判定的。实际上,引擎使用保守的近似,如可达性。预期会有很大的实现自由度。
9.9.3 执行
在任何时候,如果对象和/或符号集合S 不是活跃的 ,ECMAScript 实现可以原子地执行以下步骤:
对于S 的每个元素value ,执行
对于每个ref .[[WeakRefTarget]] 为value 的WeakRef
ref ,执行
设置ref .[[WeakRefTarget]] 为empty 。
对于每个fg .[[Cells]] 包含cell .[[WeakRefTarget]] 为value 的记录
cell 的FinalizationRegistry
fg ,执行
设置cell .[[WeakRefTarget]] 为empty 。
可选地,执行HostEnqueueFinalizationRegistryCleanupJob (fg )。
对于每个map .[[WeakMapData]] 包含r .[[Key]] 为value 的记录
r 的 WeakMap map ,执行
设置r .[[Key]] 为empty 。
设置r .[[Value]] 为empty 。
对于每个set .[[WeakSetData]] 包含value 的
WeakSet set ,执行
用值为empty 的元素替换set .[[WeakSetData]] 中值为value 的元素。
注 1
与活跃性定义一起,本条款规定了实现可以应用于WeakRefs 的优化。
可以在不观察对象身份的情况下访问对象。诸如死变量消除和对身份未被观察的非逃逸对象属性的标量替换等优化是允许的。因此,这些优化被允许可观察地清空指向此类对象的WeakRefs 。
另一方面,如果对象的身份是可观察的,并且该对象在WeakRef 的[[WeakRefTarget]] 内部槽中,则禁止可观察地清空WeakRef 的重新物化等优化。
因为调用HostEnqueueFinalizationRegistryCleanupJob 是可选的,FinalizationRegistry 中的注册对象不一定使该FinalizationRegistry 保持活跃 。实现可以因任何原因省略FinalizationRegistry 回调,例如,如果FinalizationRegistry 本身变为死亡,或者应用程序正在关闭。
注 2
实现没有义务为非活跃 对象或符号的最大集合清空WeakRefs 。
如果实现选择一个非活跃 集合S 来清空WeakRefs ,此定义要求它同时清空S 中所有值的WeakRefs 。换句话说,实现清空指向值v 的WeakRef 而不清空其他WeakRefs (如果不清空,可能导致观察到v 值的执行)是不符合规范的。
9.9.4 宿主钩子
9.9.4.1 HostEnqueueFinalizationRegistryCleanupJob (
finalizationRegistry )
宿主定义 的抽象操作
HostEnqueueFinalizationRegistryCleanupJob 接收参数finalizationRegistry (一个FinalizationRegistry ),并返回unused 。
设cleanupJob 为捕获finalizationRegistry 的无参数新作业 抽象闭包 ,调用时执行以下步骤:
设cleanupResult 为Completion (CleanupFinalizationRegistry (finalizationRegistry ))。
如果cleanupResult 是异常完成 ,执行任何宿主定义 的错误报告步骤。
返回unused 。
HostEnqueueFinalizationRegistryCleanupJob
的实现调度cleanupJob 在将来某个时间执行(如果可能)。它还必须符合9.5 中的要求。
9.10 ClearKeptObjects ( )
抽象操作 ClearKeptObjects 不接收参数,并返回unused 。预期 ECMAScript 实现在同步 ECMAScript 执行序列完成时调用
ClearKeptObjects。调用时执行以下步骤:
设agentRecord 为周围代理 的代理记录 。
设置agentRecord .[[KeptAlive]] 为一个新的空列表 。
返回unused 。
9.11 AddToKeptObjects ( value )
抽象操作 AddToKeptObjects 接收参数value (一个对象或符号),并返回unused 。调用时执行以下步骤:
设agentRecord 为周围代理 的代理记录 。
将value 追加到agentRecord .[[KeptAlive]] 。
返回unused 。
注
当抽象操作 AddToKeptObjects 使用目标对象或符号调用时,它将目标添加到一个列表中,该列表将强引用目标,直到调用
ClearKeptObjects 。
9.12 CleanupFinalizationRegistry ( finalizationRegistry )
抽象操作 CleanupFinalizationRegistry 接收参数finalizationRegistry (一个FinalizationRegistry ),并返回包含unused 的正常完成 或抛出完成 。调用时执行以下步骤:
断言 :finalizationRegistry 具有[[Cells]] 和[[CleanupCallback]] 内部槽。
设callback 为finalizationRegistry .[[CleanupCallback]] 。
当finalizationRegistry .[[Cells]] 包含cell .[[WeakRefTarget]] 为empty 的记录
cell 时,实现可以执行以下步骤:
选择任何这样的cell 。
从finalizationRegistry .[[Cells]] 中移除cell 。
执行? HostCallJobCallback (callback ,
undefined , « cell .[[HeldValue]] »)。
返回unused 。
9.13 CanBeHeldWeakly ( v )
抽象操作 CanBeHeldWeakly 接收参数v (一个ECMAScript
语言值 ),并返回一个布尔值。当且仅当v 适合用作弱引用时,它返回true 。只有适合用作弱引用的值才能作为
WeakMap 的键、WeakSet 的元素、WeakRef 的目标或FinalizationRegistry 的目标之一。调用时执行以下步骤:
如果v 是对象 ,返回true 。
如果v 是符号 且KeyForSymbol (v )为undefined ,返回true 。
返回false 。
注
没有语言身份 的语言值可以在没有先前引用的情况下体现,并且不适合用作弱引用。由Symbol.for 产生的符号值与其他符号值不同,没有语言身份,不适合用作弱引用。知名符号 可能永远不会被回收,但仍被视为适合用作弱引用,因为它们数量有限,因此可以通过各种实现方法进行管理。但是,在活跃 WeakMap
中与知名符号关联的任何值都不太可能被回收,并且在实现中可能"泄漏"内存资源。
10 普通对象和异构对象行为
10.1 普通对象内部方法和内部槽
所有普通对象 都有一个名为[[Prototype]] 的内部槽。此内部槽的值要么是null ,要么是一个对象,用于实现继承。假设一个名为P 的属性在普通对象
O 中不存在,但在其[[Prototype]] 对象上存在。如果P 引用[[Prototype]] 对象上的一个数据属性 ,O 对于get访问会继承它,使其表现得好像P 是O 的一个属性。如果P 引用[[Prototype]] 对象上的一个可写数据属性 ,对O 上P 的set访问会在O 上创建一个名为P 的新数据属性 。如果P 引用[[Prototype]] 对象上的一个不可写数据属性 ,对O 上P 的set访问会失败。如果P 引用[[Prototype]] 对象上的一个访问器属性 ,O 会继承该访问器用于get访问和set访问。
每个普通对象 都有一个布尔值[[Extensible]] 内部槽,用于满足6.1.7.3 中指定的可扩展性相关内部方法不变量。也就是说,一旦对象的[[Extensible]] 内部槽的值被设置为false ,就不再可能向对象添加属性、修改对象的[[Prototype]] 内部槽的值,或随后将[[Extensible]] 的值更改为true 。
在以下算法描述中,假设O 是一个普通对象 ,P 是一个属性键 值,V 是任何ECMAScript语言值 ,Desc 是一个属性描述符 记录。
每个普通对象 内部方法都委托给同名的抽象操作。如果这样的抽象操作依赖于另一个内部方法,那么内部方法在O 上被调用,而不是直接调用同名的抽象操作。这些语义确保当普通对象 内部方法应用于异构对象 时,它们重写的内部方法会被调用。
10.1.1 [[GetPrototypeOf]] ( )
普通对象
O 的[[GetPrototypeOf]] 内部方法不接受参数,返回一个包含 Object或null 的正常完成 。调用时执行以下步骤:
返回 OrdinaryGetPrototypeOf (O )。
10.1.1.1 OrdinaryGetPrototypeOf ( O )
抽象操作OrdinaryGetPrototypeOf接受参数O (一个Object),返回一个Object或null 。调用时执行以下步骤:
返回 O .[[Prototype]] 。
10.1.2 [[SetPrototypeOf]] ( V )
普通对象
O 的[[SetPrototypeOf]] 内部方法接受参数V (一个Object或null ),返回一个包含 Boolean的正常完成 。调用时执行以下步骤:
返回 OrdinarySetPrototypeOf (O ,
V )。
10.1.2.1 OrdinarySetPrototypeOf ( O , V )
抽象操作OrdinarySetPrototypeOf接受参数O (一个Object)和V (一个Object或null ),返回一个Boolean。调用时执行以下步骤:
令 current 为 O .[[Prototype]] 。
如果 SameValue (V ,
current ) 为 true ,返回 true 。
令 extensible 为 O .[[Extensible]] 。
如果 extensible 为 false ,返回 false 。
令 p 为 V 。
令 done 为 false 。
重复,当 done 为
false 时,
如果 p 为 null ,那么
设置 done 为 true 。
否则如果 SameValue (p ,
O ) 为 true ,那么
返回 false 。
否则,
如果 p .[[GetPrototypeOf]]
不是10.1.1 中定义的普通对象 内部方法,设置
done 为 true 。
否则,设置 p 为 p .[[Prototype]] 。
设置 O .[[Prototype]] 为 V 。
返回 true 。
注
步骤7 中的循环保证在仅包含使用[[GetPrototypeOf]] 和[[SetPrototypeOf]] 的普通对象 定义的对象的任何原型链中都不会出现循环。
10.1.3 [[IsExtensible]] ( )
普通对象
O 的[[IsExtensible]] 内部方法不接受参数,返回一个包含 Boolean的正常完成 。调用时执行以下步骤:
返回 OrdinaryIsExtensible (O )。
10.1.3.1 OrdinaryIsExtensible ( O )
抽象操作OrdinaryIsExtensible接受参数O (一个Object),返回一个Boolean。调用时执行以下步骤:
返回 O .[[Extensible]] 。
10.1.4 [[PreventExtensions]] ( )
普通对象
O 的[[PreventExtensions]] 内部方法不接受参数,返回一个包含 true 的正常完成 。调用时执行以下步骤:
返回 OrdinaryPreventExtensions (O )。
10.1.4.1 OrdinaryPreventExtensions ( O )
抽象操作OrdinaryPreventExtensions接受参数O (一个Object),返回true 。调用时执行以下步骤:
设置 O .[[Extensible]] 为 false 。
返回 true 。
10.1.5 [[GetOwnProperty]] ( P )
普通对象
O 的[[GetOwnProperty]] 内部方法接受参数P (一个属性键 ),返回一个包含 属性描述符 或undefined 的正常完成 。调用时执行以下步骤:
返回 OrdinaryGetOwnProperty (O ,
P )。
10.1.5.1 OrdinaryGetOwnProperty ( O , P )
抽象操作OrdinaryGetOwnProperty接受参数O (一个Object)和P (一个属性键 ),返回一个属性描述符 或undefined 。调用时执行以下步骤:
如果 O 没有键为 P 的自有属性,返回 undefined 。
令 D 为一个新创建的没有字段的属性描述符 。
令 X 为 O 的键为 P 的自有属性。
如果 X 是一个数据属性 ,那么
设置 D .[[Value]] 为 X 的[[Value]] 特性的值。
设置 D .[[Writable]] 为 X 的[[Writable]] 特性的值。
否则,
断言 :X 是一个访问器属性 。
设置 D .[[Get]] 为 X 的[[Get]] 特性的值。
设置 D .[[Set]] 为 X 的[[Set]] 特性的值。
设置 D .[[Enumerable]] 为 X 的[[Enumerable]] 特性的值。
设置 D .[[Configurable]] 为 X 的[[Configurable]] 特性的值。
返回 D 。
10.1.6 [[DefineOwnProperty]] (
P , Desc )
普通对象
O 的[[DefineOwnProperty]] 内部方法接受参数P (一个属性键 )和Desc (一个属性描述符 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
返回 ? OrdinaryDefineOwnProperty (O ,
P , Desc )。
10.1.6.1 OrdinaryDefineOwnProperty ( O , P ,
Desc )
抽象操作OrdinaryDefineOwnProperty接受参数O (一个Object)、P (一个属性键 )和Desc (一个属性描述符 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
令 current 为 ? O .[[GetOwnProperty]] (P )。
令 extensible 为 ? IsExtensible (O )。
返回 ValidateAndApplyPropertyDescriptor (O ,
P , extensible , Desc , current )。
10.1.6.2 IsCompatiblePropertyDescriptor ( Extensible ,
Desc , Current )
抽象操作IsCompatiblePropertyDescriptor接受参数Extensible (一个Boolean)、Desc (一个属性描述符 )和Current (一个属性描述符 或undefined ),返回一个Boolean。调用时执行以下步骤:
返回 ValidateAndApplyPropertyDescriptor (undefined ,
"" , Extensible , Desc , Current )。
10.1.6.3 ValidateAndApplyPropertyDescriptor ( O ,
P , extensible , Desc , current )
抽象操作ValidateAndApplyPropertyDescriptor接受参数O (一个Object或undefined )、P (一个属性键 )、extensible (一个Boolean)、Desc (一个属性描述符 )和current (一个属性描述符 或undefined ),返回一个Boolean。当且仅当Desc 可以作为具有指定extensibility 和当前属性current 的对象的属性应用,同时维护不变量 时,它返回true 。当这种应用是可能的且O 不是undefined 时,它对名为P 的属性执行此操作(必要时创建该属性)。调用时执行以下步骤:
断言 :P 是一个属性键 。
如果 current 为 undefined ,那么
如果 extensible 为 false ,返回
false 。
如果 O 为 undefined ,返回 true 。
如果 IsAccessorDescriptor (Desc )
为 true ,那么
在对象O 上创建一个名为P 的自有访问器属性 ,其[[Get]] 、[[Set]] 、[[Enumerable]] 和[[Configurable]] 特性分别设置为Desc 中对应字段的值(如果Desc 有该字段),否则设置为该特性的默认值 。
否则,
在对象O 上创建一个名为P 的自有数据属性 ,其[[Value]] 、[[Writable]] 、[[Enumerable]] 和[[Configurable]] 特性分别设置为Desc 中对应字段的值(如果Desc 有该字段),否则设置为该特性的默认值 。
返回 true 。
断言 :current 是一个完全填充的属性描述符 。
如果 Desc 没有任何字段,返回 true 。
如果 current .[[Configurable]] 为
false ,那么
如果 Desc 有[[Configurable]] 字段且Desc .[[Configurable]] 为 true ,返回
false 。
如果 Desc 有[[Enumerable]] 字段且Desc .[[Enumerable]] 不等于 current .[[Enumerable]] ,返回 false 。
如果 IsGenericDescriptor (Desc )
为 false 且 IsAccessorDescriptor (Desc )
不等于 IsAccessorDescriptor (current ),返回
false 。
如果 IsAccessorDescriptor (current )
为 true ,那么
如果 Desc 有[[Get]] 字段且SameValue (Desc .[[Get]] , current .[[Get]] ) 为 false ,返回
false 。
如果 Desc 有[[Set]] 字段且SameValue (Desc .[[Set]] , current .[[Set]] ) 为 false ,返回
false 。
否则如果 current .[[Writable]] 为
false ,那么
如果 Desc 有[[Writable]] 字段且Desc .[[Writable]] 为 true ,返回
false 。
注:SameValue 对NaN 值返回true ,这些值可能通过其他方式区分。在此处返回确保O 的任何现有属性保持未修改。
如果 Desc 有[[Value]] 字段,返回
SameValue (Desc .[[Value]] , current .[[Value]] )。
如果 O 不是 undefined ,那么
如果 IsDataDescriptor (current )
为 true 且 IsAccessorDescriptor (Desc )
为 true ,那么
如果 Desc 有[[Configurable]] 字段,令
configurable 为 Desc .[[Configurable]] ;否则令 configurable
为 current .[[Configurable]] 。
如果 Desc 有[[Enumerable]] 字段,令
enumerable 为 Desc .[[Enumerable]] ;否则令 enumerable 为
current .[[Enumerable]] 。
将对象O 的名为P 的属性替换为一个访问器属性 ,其[[Configurable]] 和[[Enumerable]] 特性分别设置为configurable 和enumerable ,其[[Get]] 和[[Set]] 特性设置为Desc 中对应字段的值(如果Desc 有该字段),否则设置为该特性的默认值 。
否则如果 IsAccessorDescriptor (current )
为 true 且 IsDataDescriptor (Desc )
为 true ,那么
如果 Desc 有[[Configurable]] 字段,令
configurable 为 Desc .[[Configurable]] ;否则令 configurable
为 current .[[Configurable]] 。
如果 Desc 有[[Enumerable]] 字段,令
enumerable 为 Desc .[[Enumerable]] ;否则令 enumerable 为
current .[[Enumerable]] 。
将对象O 的名为P 的属性替换为一个数据属性 ,其[[Configurable]] 和[[Enumerable]] 特性分别设置为configurable 和enumerable ,其[[Value]] 和[[Writable]] 特性设置为Desc 中对应字段的值(如果Desc 有该字段),否则设置为该特性的默认值 。
否则,
对于Desc 的每个字段,将对象O 的名为P 的属性的对应特性设置为该字段的值。
返回 true 。
10.1.7 [[HasProperty]] ( P )
普通对象
O 的[[HasProperty]] 内部方法接受参数P (一个属性键 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
返回 ? OrdinaryHasProperty (O ,
P )。
10.1.7.1 OrdinaryHasProperty ( O , P )
抽象操作OrdinaryHasProperty接受参数O (一个Object)和P (一个属性键 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
令 hasOwn 为 ? O .[[GetOwnProperty]] (P )。
如果 hasOwn 不是 undefined ,返回 true 。
令 parent 为 ? O .[[GetPrototypeOf]] ()。
如果 parent 不是 null ,那么
返回 ? parent .[[HasProperty]] (P )。
返回 false 。
10.1.8 [[Get]] ( P ,
Receiver )
普通对象
O 的[[Get]] 内部方法接受参数P (一个属性键 )和Receiver (一个ECMAScript语言值 ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
返回 ? OrdinaryGet (O , P ,
Receiver )。
10.1.8.1 OrdinaryGet ( O , P ,
Receiver )
抽象操作OrdinaryGet接受参数O (一个Object)、P (一个属性键 )和Receiver (一个ECMAScript语言值 ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
令 desc 为 ? O .[[GetOwnProperty]] (P )。
如果 desc 为 undefined ,那么
令 parent 为 ? O .[[GetPrototypeOf]] ()。
如果 parent 为 null ,返回
undefined 。
返回 ? parent .[[Get]] (P ,
Receiver )。
如果 IsDataDescriptor (desc )
为 true ,返回 desc .[[Value]] 。
断言 :IsAccessorDescriptor (desc )
为 true 。
令 getter 为 desc .[[Get]] 。
如果 getter 为 undefined ,返回 undefined 。
返回 ? Call (getter ,
Receiver )。
10.1.9 [[Set]] ( P ,
V , Receiver )
普通对象
O 的[[Set]] 内部方法接受参数P (一个属性键 )、V (一个ECMAScript语言值 )和Receiver (一个ECMAScript语言值 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
返回 ? OrdinarySet (O , P ,
V , Receiver )。
10.1.9.1 OrdinarySet ( O , P , V ,
Receiver )
抽象操作OrdinarySet接受参数O (一个Object)、P (一个属性键 )、V (一个ECMAScript语言值 )和Receiver (一个ECMAScript语言值 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
令 ownDesc 为 ? O .[[GetOwnProperty]] (P )。
返回 ? OrdinarySetWithOwnDescriptor (O ,
P , V , Receiver , ownDesc )。
10.1.9.2 OrdinarySetWithOwnDescriptor ( O ,
P , V , Receiver , ownDesc )
抽象操作OrdinarySetWithOwnDescriptor接受参数O (一个Object)、P (一个属性键 )、V (一个ECMAScript语言值 )、Receiver (一个ECMAScript语言值 )和ownDesc (一个属性描述符 或undefined ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
如果 ownDesc 为 undefined ,那么
令 parent 为 ? O .[[GetPrototypeOf]] ()。
如果 parent 不是 null ,那么
返回 ? parent .[[Set]] (P ,
V , Receiver )。
否则,
设置 ownDesc 为属性描述符 { [[Value]] :
undefined ,
[[Writable]] : true , [[Enumerable]] : true ,
[[Configurable]] :
true }。
如果 IsDataDescriptor (ownDesc )
为 true ,那么
如果 ownDesc .[[Writable]] 为
false ,返回 false 。
如果 Receiver 不是Object ,返回
false 。
令 existingDescriptor 为 ? Receiver .[[GetOwnProperty]] (P )。
如果 existingDescriptor 不是 undefined ,那么
如果 IsAccessorDescriptor (existingDescriptor )
为 true ,返回 false 。
如果 existingDescriptor .[[Writable]] 为 false ,
返回 false 。
令 valueDesc 为属性描述符 { [[Value]] :
V }。
返回 ? Receiver .[[DefineOwnProperty]] (P ,
valueDesc )。
否则,
断言 :Receiver 当前没有属性
P 。
返回 ? CreateDataProperty (Receiver ,
P , V )。
断言 :IsAccessorDescriptor (ownDesc )
为 true 。
令 setter 为 ownDesc .[[Set]] 。
如果 setter 为 undefined ,返回 false 。
执行 ? Call (setter ,
Receiver , « V »)。
返回 true 。
10.1.10 [[Delete]] ( P )
普通对象
O 的[[Delete]] 内部方法接受参数P (一个属性键 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
返回 ? OrdinaryDelete (O , P )。
10.1.10.1 OrdinaryDelete ( O , P )
抽象操作OrdinaryDelete接受参数O (一个Object)和P (一个属性键 ),返回包含 Boolean的正常完成 或抛出完成 。调用时执行以下步骤:
令 desc 为 ? O .[[GetOwnProperty]] (P )。
如果 desc 为 undefined ,返回 true 。
如果 desc .[[Configurable]] 为
true ,那么
从 O 中移除名为 P 的自有属性。
返回 true 。
返回 false 。
10.1.11 [[OwnPropertyKeys]] ( )
普通对象
O 的[[OwnPropertyKeys]] 内部方法不接受参数,返回一个包含 属性键 的列表 的正常完成 。调用时执行以下步骤:
返回 OrdinaryOwnPropertyKeys (O )。
10.1.11.1 OrdinaryOwnPropertyKeys ( O )
抽象操作OrdinaryOwnPropertyKeys接受参数O (一个Object),返回一个属性键 的列表 。调用时执行以下步骤:
令 keys 为一个新的空列表 。
对于 O 的每个自有属性键 P ,满足 P
是数组索引 ,按升序数字索引顺序,执行
将 P 追加到 keys 。
对于 O 的每个自有属性键 P ,满足 P
是字符串 且
P 不是数组索引 ,按属性创建的升序时间顺序,执行
将 P 追加到 keys 。
对于 O 的每个自有属性键 P ,满足 P
是Symbol ,按属性创建的升序时间顺序,执行
将 P 追加到 keys 。
返回 keys 。
10.1.12 OrdinaryObjectCreate ( proto [ ,
additionalInternalSlotsList ] )
抽象操作OrdinaryObjectCreate接受参数proto (一个Object或null )和可选参数additionalInternalSlotsList (内部插槽名称的列表 ),返回一个Object。它用于指定新普通对象 的运行时创建。additionalInternalSlotsList 包含除[[Prototype]] 和[[Extensible]] 之外必须作为对象一部分定义的附加内部插槽的名称。如果未提供additionalInternalSlotsList ,则使用一个新的空列表 。调用时执行以下步骤:
令 internalSlotsList 为 « [[Prototype]] , [[Extensible]] »。
如果 additionalInternalSlotsList 存在,设置 internalSlotsList 为
internalSlotsList 和 additionalInternalSlotsList 的列表连接 。
令 O 为 MakeBasicObject (internalSlotsList )。
设置 O .[[Prototype]] 为 proto 。
返回 O 。
注
虽然OrdinaryObjectCreate除了调用MakeBasicObject 之外没有做更多的事情,但它的使用传达了创建普通对象 而不是奇异对象的意图。因此,在本规范中,任何随后以会使结果变成非普通对象的方式修改对象内部方法的算法都不会调用它。创建奇异对象 的操作直接调用MakeBasicObject 。
10.1.13 OrdinaryCreateFromConstructor ( constructor ,
intrinsicDefaultProto [ , internalSlotsList ] )
抽象操作OrdinaryCreateFromConstructor接受参数constructor (一个函数对象 )和intrinsicDefaultProto (一个字符串)以及可选参数internalSlotsList (内部插槽名称的列表 ),返回包含 Object的正常完成 或抛出完成 。它创建一个普通对象 ,其[[Prototype]] 值从构造器 的"prototype" 属性中检索(如果存在)。否则,由intrinsicDefaultProto 命名的内在值用于[[Prototype]] 。internalSlotsList 包含必须作为对象一部分定义的附加内部插槽的名称。如果未提供internalSlotsList ,则使用一个新的空列表 。调用时执行以下步骤:
断言 :intrinsicDefaultProto 是本规范的内在对象名称。对应的对象必须是旨在用作对象的[[Prototype]] 值的内在值。
令 proto 为 ? GetPrototypeFromConstructor (constructor ,
intrinsicDefaultProto )。
如果 internalSlotsList 存在,令 slotsList 为
internalSlotsList 。
否则,令 slotsList 为一个新的空列表 。
返回 OrdinaryObjectCreate (proto ,
slotsList )。
10.1.14 GetPrototypeFromConstructor ( constructor ,
intrinsicDefaultProto )
抽象操作GetPrototypeFromConstructor接受参数constructor (一个函数对象 )和intrinsicDefaultProto (一个字符串),返回包含 Object的正常完成 或抛出完成 。它确定应该用于创建对应于特定构造器 的对象的[[Prototype]] 值。该值从构造器 的"prototype" 属性中检索(如果存在)。否则,由intrinsicDefaultProto 命名的内在值用于[[Prototype]] 。调用时执行以下步骤:
断言 :intrinsicDefaultProto 是本规范的内在对象名称。对应的对象必须是旨在用作对象的[[Prototype]] 值的内在值。
令 proto 为 ? Get (constructor ,
"prototype" )。
如果 proto 不是Object ,那么
令 realm 为 ? GetFunctionRealm (constructor )。
设置 proto 为 realm 的名为 intrinsicDefaultProto
的内在对象。
返回 proto 。
注
如果constructor 不提供[[Prototype]] 值,则使用的默认值从constructor 函数的领域 获得,而不是从运行执行上下文 获得。
10.1.15 RequireInternalSlot ( O , internalSlot
)
抽象操作RequireInternalSlot接受参数O (一个ECMAScript语言值 )和internalSlot (一个内部插槽名称),返回包含 unused 的正常完成 或抛出完成 。除非O
是Object 且具有给定的内部插槽,否则它会抛出异常。调用时执行以下步骤:
如果 O 不是Object ,抛出 TypeError
异常。
如果 O 没有 internalSlot 内部插槽,抛出 TypeError 异常。
返回 unused 。
10.2 ECMAScript函数对象
ECMAScript函数对象 封装了在词法环境上封闭的参数化ECMAScript代码,并支持该代码的动态评估。ECMAScript函数对象 是一个普通对象 ,具有与其他普通对象 相同的内部插槽和相同的内部方法。ECMAScript函数对象 的代码可以是严格模式代码 (11.2.2 )或非严格代码 。代码为严格模式代码 的ECMAScript函数对象 称为严格函数 。代码不是严格模式代码 的称为非严格函数 。
除了[[Extensible]] 和[[Prototype]] 之外,ECMAScript函数对象 还具有表30 中列出的内部插槽。
表30:ECMAScript函数对象的内部插槽
内部插槽
类型
描述
[[Environment]]
一个环境记录
函数封闭的环境记录 。在评估函数代码时用作外部环境。
[[PrivateEnvironment]]
一个私有环境记录 或null
函数封闭的私有名称 的私有环境记录 。如果此函数在语法上不包含在类中,则为null 。在评估函数代码时用作内部类的外部私有环境。
[[FormalParameters]]
一个解析节点
定义函数形式参数列表的源文本的根解析节点。
[[ECMAScriptCode]]
一个解析节点
定义函数体的源文本的根解析节点。
[[ConstructorKind]]
base 或derived
函数是否为派生类构造器 。
[[Realm]]
一个领域记录
创建函数的领域 ,它提供在评估函数时访问的任何内在对象。
[[ScriptOrModule]]
一个脚本记录 或一个模块记录
创建函数的脚本或模块。
[[ThisMode]]
lexical 、strict 或global
定义如何在函数的形式参数和代码体中解释this引用。lexical 表示this引用词法封闭函数的this 值。strict 表示this 值完全按照函数调用提供的使用。global 表示undefined 或null 的this 值被解释为对全局对象 的引用,任何其他this 值首先传递给ToObject 。
[[Strict]]
一个Boolean
如果这是严格函数 则为true ,如果这是非严格函数 则为false 。
[[HomeObject]]
一个Object
如果函数使用super,这是其[[GetPrototypeOf]] 提供super属性查找开始的对象的对象。
[[SourceText]]
Unicode代码点序列
定义函数的源文本 。
[[Fields]]
类字段定义记录 的列表
如果函数是类,这是表示类的非静态字段和相应初始化器的记录 列表。
[[PrivateMethods]]
私有元素 的列表
如果函数是类,这是表示类的非静态私有方法和访问器的列表。
[[ClassFieldInitializerName]]
一个字符串、一个Symbol、一个私有名称 或empty
如果函数是作为类字段的初始化器创建的,则为字段的命名评估 使用的名称;否则为empty 。
[[IsClassConstructor]]
一个Boolean
指示函数是否为类构造器 。(如果为true ,调用函数的[[Call]] 将立即抛出TypeError 异常。)
所有ECMAScript函数对象 都有此处定义的[[Call]] 内部方法。同时也是构造器 的ECMAScript函数另外还有[[Construct]] 内部方法。
10.2.1 [[Call]] ( thisArgument ,
argumentsList )
ECMAScript函数对象 F 的[[Call]] 内部方法接受参数thisArgument (一个ECMAScript语言值 )和argumentsList (ECMAScript语言值 的列表 ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
令 callerContext 为运行执行上下文 。
令 calleeContext 为 PrepareForOrdinaryCall (F ,
undefined )。
断言 :calleeContext 现在是运行执行上下文 。
如果 F .[[IsClassConstructor]] 为
true ,那么
令 error 为新创建的 TypeError 对象。
注:error 在calleeContext 中使用F 的关联领域记录 创建。
从执行上下文栈 中移除calleeContext 并恢复callerContext 为运行执行上下文 。
返回 ThrowCompletion (error )。
执行 OrdinaryCallBindThis (F ,
calleeContext , thisArgument )。
令 result 为 Completion (OrdinaryCallEvaluateBody (F ,
argumentsList ))。
从执行上下文栈 中移除calleeContext 并恢复callerContext 为运行执行上下文 。
如果 result 是返回完成 ,返回
result .[[Value]] 。
断言 :result 是抛出完成 。
返回 ? result 。
注
当在步骤7 中从执行上下文栈 中移除calleeContext 时,如果它被挂起并保留以供可访问的生成器稍后恢复,则不得销毁它。
10.2.1.1 PrepareForOrdinaryCall ( F ,
newTarget )
抽象操作PrepareForOrdinaryCall接受参数F (一个ECMAScript函数对象 )和newTarget (一个Object或undefined ),返回一个执行上下文 。调用时执行以下步骤:
令 callerContext 为运行执行上下文 。
令 calleeContext 为新的ECMAScript代码执行上下文 。
设置 calleeContext 的Function为 F 。
令 calleeRealm 为 F .[[Realm]] 。
设置 calleeContext 的领域 为 calleeRealm 。
设置 calleeContext 的ScriptOrModule为 F .[[ScriptOrModule]] 。
令 localEnv 为 NewFunctionEnvironment (F ,
newTarget )。
设置 calleeContext 的LexicalEnvironment为 localEnv 。
设置 calleeContext 的VariableEnvironment为 localEnv 。
设置 calleeContext 的PrivateEnvironment为 F .[[PrivateEnvironment]] 。
如果 callerContext 尚未挂起,挂起 callerContext 。
将 calleeContext 推入执行上下文栈 ;calleeContext 现在是运行执行上下文 。
注:此点之后产生的任何异常对象都与 calleeRealm 关联。
返回 calleeContext 。
10.2.1.2 OrdinaryCallBindThis ( F ,
calleeContext , thisArgument )
抽象操作OrdinaryCallBindThis接受参数F (一个ECMAScript函数对象 )、calleeContext (一个执行上下文 )和thisArgument (一个ECMAScript语言值 ),返回unused 。调用时执行以下步骤:
令 thisMode 为 F .[[ThisMode]] 。
如果 thisMode 为 lexical ,返回
unused 。
令 calleeRealm 为 F .[[Realm]] 。
令 localEnv 为 calleeContext 的LexicalEnvironment。
如果 thisMode 为 strict ,那么
令 thisValue 为 thisArgument 。
否则,
如果 thisArgument 为 undefined 或
null ,那么
令 globalEnv 为 calleeRealm .[[GlobalEnv]] 。
断言 :globalEnv 是全局环境记录 。
令 thisValue 为 globalEnv .[[GlobalThisValue]] 。
否则,
令 thisValue 为 ! ToObject (thisArgument )。
注:ToObject 使用calleeRealm 产生包装器对象。
断言 :localEnv 是函数环境记录 。
断言 :下一步永远不会返回突然完成 ,因为localEnv .[[ThisBindingStatus]] 不是initialized 。
执行 ! BindThisValue (localEnv ,
thisValue )。
返回 unused 。
10.2.1.3 运行时语义:EvaluateBody
语法导向操作 EvaluateBody接受参数functionObject (一个ECMAScript函数对象 )和argumentsList (ECMAScript语言值 的列表 ),返回返回完成 或抛出完成 。它在以下产生式上分段定义:
FunctionBody :
FunctionStatementList
返回 ? FunctionBody 的 EvaluateFunctionBody ,参数为
functionObject 和 argumentsList 。
ConciseBody :
ExpressionBody
返回 ? ConciseBody 的 EvaluateConciseBody ,参数为
functionObject 和 argumentsList 。
GeneratorBody :
FunctionBody
返回 ? GeneratorBody 的 EvaluateGeneratorBody ,参数为
functionObject 和 argumentsList 。
AsyncGeneratorBody
: FunctionBody
返回 ? AsyncGeneratorBody 的 EvaluateAsyncGeneratorBody ,参数为
functionObject 和 argumentsList 。
AsyncFunctionBody
: FunctionBody
返回 ? AsyncFunctionBody 的 EvaluateAsyncFunctionBody ,参数为
functionObject 和 argumentsList 。
AsyncConciseBody
: ExpressionBody
返回 ? AsyncConciseBody 的 EvaluateAsyncConciseBody ,参数为
functionObject 和 argumentsList 。
Initializer :
=
AssignmentExpression
断言 :argumentsList 为空。
断言 :functionObject .[[ClassFieldInitializerName]] 不是empty 。
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 为
true ,那么
令 value 为 ? Initializer 的 NamedEvaluation ,参数为
functionObject .[[ClassFieldInitializerName]] 。
否则,
令 rhs 为 ? AssignmentExpression
的 Evaluation 。
令 value 为 ? GetValue (rhs )。
返回 ReturnCompletion (value )。
注
尽管字段初始化器构成函数边界,但调用FunctionDeclarationInstantiation 没有任何可观察的效果,因此被省略。
ClassStaticBlockBody
: ClassStaticBlockStatementList
断言 :argumentsList 为空。
返回 ? ClassStaticBlockBody 的
EvaluateClassStaticBlockBody ,参数为
functionObject 。
10.2.1.4 OrdinaryCallEvaluateBody ( F ,
argumentsList )
抽象操作OrdinaryCallEvaluateBody接受参数F (一个ECMAScript函数对象 )和argumentsList (ECMAScript语言值 的列表 ),返回返回完成 或抛出完成 。调用时执行以下步骤:
返回 ? F .[[ECMAScriptCode]] 的 EvaluateBody ,参数为 F 和
argumentsList 。
10.2.2 [[Construct]] (
argumentsList , newTarget )
ECMAScript函数对象 F 的[[Construct]] 内部方法接受参数argumentsList (ECMAScript语言值 的列表 )和newTarget (一个构造器 ),返回包含 Object的正常完成 或抛出完成 。调用时执行以下步骤:
令 callerContext 为运行执行上下文 。
令 kind 为 F .[[ConstructorKind]] 。
如果 kind 为 base ,那么
令 thisArgument 为 ? OrdinaryCreateFromConstructor (newTarget ,
"%Object.prototype%" )。
令 calleeContext 为 PrepareForOrdinaryCall (F ,
newTarget )。
断言 :calleeContext 现在是运行执行上下文 。
如果 kind 为 base ,那么
执行 OrdinaryCallBindThis (F ,
calleeContext , thisArgument )。
令 initializeResult 为 Completion (InitializeInstanceElements (thisArgument ,
F ))。
如果 initializeResult 是突然完成 ,那么
从执行上下文栈 中移除calleeContext 并恢复callerContext 为运行执行上下文 。
返回 ? initializeResult 。
令 constructorEnv 为 calleeContext 的LexicalEnvironment。
令 result 为 Completion (OrdinaryCallEvaluateBody (F ,
argumentsList ))。
从执行上下文栈 中移除calleeContext 并恢复callerContext 为运行执行上下文 。
如果 result 是抛出完成 ,那么
返回 ? result 。
断言 :result 是返回完成 。
如果 result .[[Value]] 是Object ,返回 result .[[Value]] 。
如果 kind 为 base ,返回 thisArgument 。
如果 result .[[Value]] 不是
undefined ,抛出 TypeError 异常。
令 thisBinding 为 ? constructorEnv .GetThisBinding()。
断言 :thisBinding 是Object 。
返回 thisBinding 。
10.2.3 OrdinaryFunctionCreate ( functionPrototype ,
sourceText , ParameterList , Body , thisMode ,
env , privateEnv )
抽象操作OrdinaryFunctionCreate接受参数functionPrototype (一个Object)、sourceText (Unicode代码点序列)、ParameterList (一个解析节点 )、Body (一个解析节点 )、thisMode (lexical-this 或non-lexical-this )、env (一个环境记录 )和privateEnv (一个私有环境记录 或null ),返回一个ECMAScript函数对象 。它用于指定运行时创建具有默认[[Call]] 内部方法且没有[[Construct]] 内部方法的新函数(尽管随后可能通过诸如MakeConstructor 之类的操作添加一个)。sourceText 是要创建的函数的语法定义的源文本。调用时执行以下步骤:
令 internalSlotsList 为表30 中列出的内部插槽。
令 F 为 OrdinaryObjectCreate (functionPrototype ,
internalSlotsList )。
设置 F .[[Call]] 为10.2.1 中指定的定义。
设置 F .[[SourceText]] 为 sourceText 。
设置 F .[[FormalParameters]] 为
ParameterList 。
设置 F .[[ECMAScriptCode]] 为 Body 。
令 Strict 为 IsStrict (Body )。
设置 F .[[Strict]] 为 Strict 。
如果 thisMode 为 lexical-this ,设置 F .[[ThisMode]] 为 lexical 。
否则,如果 Strict 为 true ,设置 F .[[ThisMode]] 为 strict 。
否则,设置 F .[[ThisMode]] 为
global 。
设置 F .[[IsClassConstructor]] 为
false 。
设置 F .[[Environment]] 为 env 。
设置 F .[[PrivateEnvironment]] 为 privateEnv 。
设置 F .[[ScriptOrModule]] 为 GetActiveScriptOrModule ()。
设置 F .[[Realm]] 为当前领域记录 。
设置 F .[[HomeObject]] 为 undefined 。
设置 F .[[Fields]] 为新的空列表 。
设置 F .[[PrivateMethods]] 为新的空列表 。
设置 F .[[ClassFieldInitializerName]] 为
empty 。
令 len 为 ParameterList 的ExpectedArgumentCount 。
执行 SetFunctionLength (F ,
len )。
返回 F 。
10.2.4 AddRestrictedFunctionProperties ( F ,
realm )
抽象操作AddRestrictedFunctionProperties接受参数F (一个函数对象 )和realm (一个领域记录 ),返回unused 。调用时执行以下步骤:
断言 :realm .[[Intrinsics]] .[[%ThrowTypeError% ]]存在且已被初始化。
令 thrower 为 realm .[[Intrinsics]] .[[%ThrowTypeError% ]]。
执行 ! DefinePropertyOrThrow (F ,
"caller" , PropertyDescriptor { [[Get]] :
thrower , [[Set]] : thrower , [[Enumerable]] : false , [[Configurable]] : true })。
执行 ! DefinePropertyOrThrow (F ,
"arguments" , PropertyDescriptor { [[Get]] :
thrower , [[Set]] : thrower , [[Enumerable]] : false , [[Configurable]] : true })。
返回 unused 。
10.2.4.1 %ThrowTypeError% ( )
此函数是%ThrowTypeError% 内在对象。
它是一个匿名的内置函数对象 ,为每个领域 定义一次。
调用时执行以下步骤:
抛出 TypeError 异常。
此函数的[[Extensible]] 内部插槽的值为false 。
此函数的"length" 属性具有特性{ [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
此函数的"name" 属性具有特性{ [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
10.2.5 MakeConstructor ( F [ ,
writablePrototype [ , prototype ] ] )
抽象操作MakeConstructor接受参数F (一个ECMAScript函数对象 或内置函数对象 )和可选参数writablePrototype (一个Boolean)和prototype (一个Object),返回unused 。它将F 转换为构造器 。调用时执行以下步骤:
如果 F 是ECMAScript函数对象 ,那么
断言 :IsConstructor (F ) 为
false 。
断言 :F 是一个可扩展对象,且没有"prototype" 自身属性。
设置 F .[[Construct]] 为10.2.2 中指定的定义。
否则,
设置 F .[[Construct]] 为10.3.2 中指定的定义。
设置 F .[[ConstructorKind]] 为
base 。
如果 writablePrototype 不存在,设置 writablePrototype 为
true 。
如果 prototype 不存在,那么
设置 prototype 为 OrdinaryObjectCreate (%Object.prototype% )。
执行 ! DefinePropertyOrThrow (prototype ,
"constructor" , PropertyDescriptor { [[Value]] : F , [[Writable]] : writablePrototype , [[Enumerable]] : false , [[Configurable]] : true })。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] :
writablePrototype , [[Enumerable]] :
false , [[Configurable]] :
false })。
返回 unused 。
10.2.6 MakeClassConstructor ( F )
抽象操作MakeClassConstructor接受参数F (一个ECMAScript函数对象 ),返回unused 。调用时执行以下步骤:
断言 :F .[[IsClassConstructor]] 为 false 。
设置 F .[[IsClassConstructor]] 为
true 。
返回 unused 。
10.2.7 MakeMethod ( F , homeObject )
抽象操作MakeMethod接受参数F (一个ECMAScript函数对象 )和homeObject (一个Object),返回unused 。它将F 配置为方法。调用时执行以下步骤:
断言 :homeObject 是普通对象 。
设置 F .[[HomeObject]] 为 homeObject 。
返回 unused 。
10.2.8 DefineMethodProperty ( homeObject , key ,
closure , enumerable )
抽象操作DefineMethodProperty接受参数homeObject (一个Object)、key (一个属性键 或私有名称 )、closure (一个函数对象 )和enumerable (一个Boolean),返回包含 私有元素 或unused 的正常完成 ,或突然完成 。调用时执行以下步骤:
断言 :homeObject 是普通的、可扩展的对象。
如果 key 是私有名称 ,那么
返回 私有元素 { [[Key]] : key , [[Kind]] : method , [[Value]] : closure }。
否则,
令 desc 为PropertyDescriptor { [[Value]] :
closure , [[Writable]] :
true , [[Enumerable]] :
enumerable , [[Configurable]] :
true }。
执行 ? DefinePropertyOrThrow (homeObject ,
key , desc )。
注:DefinePropertyOrThrow 仅在尝试定义key 为"prototype" 的类静态方法时返回突然完成 。
返回 unused 。
10.2.9 SetFunctionName ( F , name [ ,
prefix ] )
抽象操作SetFunctionName接受参数F (一个函数对象 )和name (一个属性键 或私有名称 )和可选参数prefix (一个String),返回unused 。它为F 添加"name" 属性。调用时执行以下步骤:
断言 :F 是可扩展对象且没有"name" 自身属性。
如果 name 是Symbol ,那么
令 description 为 name 的[[Description]] 值。
如果 description 为 undefined ,设置 name
为空字符串。
否则,设置 name
为"[" 、description 和"]" 的字符串连接 。
否则,如果 name 是私有名称 ,那么
设置 name 为 name .[[Description]] 。
如果 F 有[[InitialName]] 内部插槽,那么
设置 F .[[InitialName]] 为 name 。
如果 prefix 存在,那么
设置 name 为prefix 、代码单元0x0020(空格)和name 的字符串连接 。
如果 F 有[[InitialName]] 内部插槽,那么
可选地,设置 F .[[InitialName]] 为
name 。
执行 ! DefinePropertyOrThrow (F ,
"name" , PropertyDescriptor { [[Value]] :
name , [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true })。
返回 unused 。
10.2.10 SetFunctionLength ( F , length )
抽象操作SetFunctionLength接受参数F (一个函数对象 )和length (非负整数 或+∞),返回unused 。它为F 添加"length" 属性。调用时执行以下步骤:
断言 :F 是可扩展对象且没有"length" 自身属性。
执行 ! DefinePropertyOrThrow (F ,
"length" , PropertyDescriptor { [[Value]] :
𝔽 (length ),
[[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true })。
返回 unused 。
10.2.11 FunctionDeclarationInstantiation ( func ,
argumentsList )
抽象操作FunctionDeclarationInstantiation接受参数func (一个ECMAScript函数对象 )和argumentsList (ECMAScript语言值 的列表 ),返回包含 unused 的正常完成 或突然完成 。func 是正在为其建立执行上下文 的函数对象 。
注1
当为评估ECMAScript函数建立执行上下文 时,会创建新的函数环境记录 ,并在该环境记录 中实例化每个形参的绑定。函数体中的每个声明也会被实例化。如果函数的形参不包含任何默认值初始化器,则函数体声明会在与参数相同的环境记录 中实例化。如果存在默认值参数初始化器,则为函数体声明创建第二个环境记录 。形参和函数作为FunctionDeclarationInstantiation的一部分被初始化。所有其他绑定在函数体评估期间被初始化。
调用时执行以下步骤:
令 calleeContext 为运行执行上下文 。
令 code 为 func .[[ECMAScriptCode]] 。
令 strict 为 func .[[Strict]] 。
令 formals 为 func .[[FormalParameters]] 。
令 parameterNames 为 formals 的BoundNames 。
如果 parameterNames 有任何重复条目,令 hasDuplicates 为
true 。否则,令 hasDuplicates 为 false 。
令 simpleParameterList 为 formals 的IsSimpleParameterList 。
令 hasParameterExpressions 为 formals 的ContainsExpression 。
令 varNames 为 code 的VarDeclaredNames 。
令 varDeclarations 为 code 的VarScopedDeclarations 。
令 lexicalNames 为 code 的LexicallyDeclaredNames 。
令 functionNames 为新的空列表 。
令 functionsToInitialize 为新的空列表 。
对于 varDeclarations 的每个元素 d ,按反向列表 顺序,执行
如果 d 既不是VariableDeclaration ,也不是ForBinding ,也不是BindingIdentifier ,那么
断言 :d 要么是FunctionDeclaration ,要么是GeneratorDeclaration ,要么是AsyncFunctionDeclaration ,要么是AsyncGeneratorDeclaration 。
令 fn 为 d 的BoundNames 的唯一元素。
如果 functionNames 不包含 fn ,那么
将 fn 作为第一个元素插入 functionNames 。
注:如果有多个同名函数声明,使用最后一个声明。
将 d 作为第一个元素插入 functionsToInitialize 。
令 argumentsObjectNeeded 为 true 。
如果 func .[[ThisMode]] 为
lexical ,那么
注:箭头函数从不有arguments对象。
设置 argumentsObjectNeeded 为 false 。
否则,如果 parameterNames 包含 "arguments" ,那么
设置 argumentsObjectNeeded 为 false 。
否则,如果 hasParameterExpressions 为 false ,那么
如果 functionNames 包含 "arguments" 或
lexicalNames 包含 "arguments" ,那么
设置 argumentsObjectNeeded 为 false 。
如果 strict 为 true 或 hasParameterExpressions 为
false ,那么
注:由于严格模式代码 中对eval的调用不能创建在eval之外可见的新绑定,因此参数只需要单一的环境记录 。
令 env 为 calleeContext 的LexicalEnvironment。
否则,
注:需要单独的环境记录 以确保形参列表中直接eval 调用创建的绑定位于声明参数的环境之外。
令 calleeEnv 为 calleeContext 的LexicalEnvironment。
令 env 为 NewDeclarativeEnvironment (calleeEnv )。
断言 :calleeContext
的VariableEnvironment和 calleeEnv 是同一个环境记录 。
设置 calleeContext 的LexicalEnvironment为 env 。
对于 parameterNames 的每个字符串 paramName ,执行
令 alreadyDeclared 为
! env .HasBinding(paramName )。
注:早期错误 确保重复参数名只能出现在没有参数默认值或剩余参数的非严格函数 中。
如果 alreadyDeclared 为 false ,那么
执行 ! env .CreateMutableBinding(paramName ,
false )。
如果 hasDuplicates 为 true ,那么
执行 ! env .InitializeBinding(paramName ,
undefined )。
如果 argumentsObjectNeeded 为 true ,那么
如果 strict 为 true 或 simpleParameterList
为 false ,那么
令 ao 为 CreateUnmappedArgumentsObject (argumentsList )。
否则,
注:映射的参数对象仅为没有剩余参数、任何参数默认值初始化器或任何解构参数的非严格函数 提供。
令 ao 为 CreateMappedArgumentsObject (func ,
formals , argumentsList , env )。
如果 strict 为 true ,那么
执行
! env .CreateImmutableBinding("arguments" ,
false )。
注:在严格模式代码 中,早期错误 防止尝试赋值给此绑定,因此其可变性不可观察。
否则,
执行
! env .CreateMutableBinding("arguments" ,
false )。
执行 ! env .InitializeBinding("arguments" ,
ao )。
令 parameterBindings 为 parameterNames 和 «
"arguments" » 的列表连接 。
否则,
令 parameterBindings 为 parameterNames 。
令 iteratorRecord 为 CreateListIteratorRecord (argumentsList )。
如果 hasDuplicates 为 true ,那么
执行 ? formals 的IteratorBindingInitialization ,参数为
iteratorRecord 和 undefined 。
否则,
执行 ? formals 的IteratorBindingInitialization ,参数为
iteratorRecord 和 env 。
如果 hasParameterExpressions 为 false ,那么
注:参数和顶级var只需要单一的环境记录 。
令 instantiatedVarNames 为列表
parameterBindings 的副本。
对于 varNames 的每个元素 n ,执行
如果 instantiatedVarNames 不包含 n ,那么
将 n 追加到 instantiatedVarNames 。
执行 ! env .CreateMutableBinding(n ,
false )。
执行 ! env .InitializeBinding(n ,
undefined )。
令 varEnv 为 env 。
否则,
注:需要单独的环境记录 以确保形参列表中表达式创建的闭包不能看到函数体中的声明。
令 varEnv 为 NewDeclarativeEnvironment (env )。
设置 calleeContext 的VariableEnvironment为 varEnv 。
令 instantiatedVarNames 为新的空列表 。
对于 varNames 的每个元素 n ,执行
如果 instantiatedVarNames 不包含 n ,那么
将 n 追加到 instantiatedVarNames 。
执行 ! varEnv .CreateMutableBinding(n ,
false )。
如果 parameterBindings 不包含 n ,或如果
functionNames 包含 n ,那么
令 initialValue 为
undefined 。
否则,
令 initialValue 为
! env .GetBindingValue(n ,
false )。
执行 ! varEnv .InitializeBinding(n ,
initialValue )。
注:与形参同名的var最初具有与相应初始化参数相同的值。
注:附录B.3.2.1 在此处添加了额外的步骤。
如果 strict 为 false ,那么
令 lexEnv 为 NewDeclarativeEnvironment (varEnv )。
注:非严格函数 对顶级词法声明使用单独的环境记录 ,以便直接eval 可以确定eval代码引入的任何var作用域声明是否与预先存在的顶级词法作用域声明冲突。这对于严格函数 不是必需的,因为严格的直接eval 总是将所有声明放入新的环境记录 中。
否则,
令 lexEnv 为 varEnv 。
设置 calleeContext 的LexicalEnvironment为 lexEnv 。
令 lexDeclarations 为 code 的LexicallyScopedDeclarations 。
对于 lexDeclarations 的每个元素 d ,执行
注:词法声明的名称不能与函数/生成器声明、形参或var名称相同。词法声明的名称仅在此处实例化但未初始化。
对于 d 的BoundNames 的每个元素
dn ,执行
如果 d 的IsConstantDeclaration 为
true ,那么
执行
! lexEnv .CreateImmutableBinding(dn ,
true )。
否则,
执行 ! lexEnv .CreateMutableBinding(dn ,
false )。
令 privateEnv 为 calleeContext 的PrivateEnvironment。
对于 functionsToInitialize 的每个解析节点 f ,执行
令 fn 为 f 的BoundNames 的唯一元素。
令 fo 为 f 的InstantiateFunctionObject ,参数为
lexEnv 和 privateEnv 。
执行 ! varEnv .SetMutableBinding(fn , fo ,
false )。
返回 unused 。
注2
B.3.2 为上述算法提供了扩展,这对于与早于ECMAScript
2015的ECMAScript的Web浏览器实现的向后兼容性是必需的。
10.3 内置函数对象
内置函数对象 是普通对象 ;它必须满足10.1 中规定的普通对象 的要求。
除了每个普通对象 所需的内部插槽(见10.1 )之外,内置函数对象 还必须具有以下内部插槽:
[[Realm]] ,一个领域记录 ,表示创建函数的领域 。
[[InitialName]] ,一个字符串,是函数的初始名称。它被20.2.3.5 使用。
内置函数对象 的[[Prototype]] 内部插槽的初始值是%Function.prototype% ,除非另有规定。
内置函数对象 必须具有符合10.3.1 中定义的[[Call]] 内部方法。
内置函数对象 当且仅当它被描述为"构造器 ",或者本规范中的某个算法明确设置其[[Construct]] 内部方法时,才具有[[Construct]] 内部方法。这样的[[Construct]] 内部方法必须符合10.3.2 中的定义。
实现可以提供本规范中未定义的其他内置函数对象 。
10.3.1 [[Call]] ( thisArgument ,
argumentsList )
内置函数对象
F 的[[Call]] 内部方法接受参数thisArgument (ECMAScript语言值 )和argumentsList (ECMAScript语言值 的列表 ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
返回 ? BuiltinCallOrConstruct (F ,
thisArgument , argumentsList , undefined )。
10.3.2 [[Construct]] (
argumentsList , newTarget )
内置函数对象
F 的[[Construct]] 内部方法(当该方法存在时)接受参数argumentsList (ECMAScript语言值 的列表 )和newTarget (一个构造器 ),返回包含 Object的正常完成 或抛出完成 。调用时执行以下步骤:
令 result 为 ? BuiltinCallOrConstruct (F ,
uninitialized , argumentsList , newTarget )。
断言 :result 是Object 。
返回 result 。
10.3.3 BuiltinCallOrConstruct ( F ,
thisArgument , argumentsList , newTarget )
抽象操作BuiltinCallOrConstruct接受参数F (内置函数对象 )、thisArgument (ECMAScript语言值 或uninitialized )、argumentsList (ECMAScript语言值 的列表 )和newTarget (构造器 或undefined ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
令 callerContext 为运行执行上下文 。
如果 callerContext 尚未被挂起,挂起 callerContext 。
令 calleeContext 为新的执行上下文 。
设置 calleeContext 的Function为 F 。
令 calleeRealm 为 F .[[Realm]] 。
设置 calleeContext 的领域 为 calleeRealm 。
设置 calleeContext 的ScriptOrModule为 null 。
执行 calleeContext 的任何必要的实现定义的 初始化。
将 calleeContext 推入执行上下文栈 ;calleeContext
现在是运行执行上下文 。
令 result 为完成记录 ,其为评估结果 ,以符合 F 规范的方式评估 F 。如果
thisArgument 为 uninitialized ,则 this
值未初始化;否则,thisArgument 提供 this 值。argumentsList
提供具名参数。newTarget 提供NewTarget值。
注:如果 F 在本文档中定义,"F 的规范"是通过算法步骤或其他方式为其指定的行为。
从执行上下文栈 中移除
calleeContext 并将 callerContext 恢复为运行执行上下文 。
返回 ? result 。
注
当从执行上下文栈 中移除
calleeContext 时,如果它已被挂起并被可访问的生成器保留以供稍后恢复,则不得销毁它。
10.3.4 CreateBuiltinFunction ( behaviour ,
length , name , additionalInternalSlotsList [ , realm
[ , prototype [ , prefix ] ] ] )
抽象操作CreateBuiltinFunction接受参数behaviour (抽象闭包 、一组算法步骤或本规范中提供的函数行为的某些其他定义)、length (非负整数 或+∞)、name (属性键 或私有名称 )和additionalInternalSlotsList (内部插槽名称的列表 )和可选参数realm (领域记录 )、prototype (Object或null )和prefix (字符串),返回内置函数对象 。additionalInternalSlotsList
包含必须作为对象的一部分定义的其他内部插槽的名称。此操作创建内置函数对象 。调用时执行以下步骤:
如果 realm 不存在,设置 realm 为当前领域记录 。
如果 prototype 不存在,设置 prototype 为
realm .[[Intrinsics]] .[[%Function.prototype% ]]。
令 internalSlotsList 为列表 ,包含10.3 为即将创建的内置函数对象 所需的所有内部插槽的名称。
将 additionalInternalSlotsList 的元素追加到 internalSlotsList 。
令 func 为新的内置函数对象 ,当调用时,使用提供的参数作为 behaviour
指定的相应参数的值,执行 behaviour 描述的操作。新的函数对象 具有名称为
internalSlotsList 元素的内部插槽,以及 [[InitialName]] 内部插槽。
设置 func .[[Prototype]] 为 prototype 。
设置 func .[[Extensible]] 为 true 。
设置 func .[[Realm]] 为 realm 。
设置 func .[[InitialName]] 为 null 。
执行 SetFunctionLength (func ,
length )。
如果 prefix 不存在,那么
执行 SetFunctionName (func ,
name )。
否则,
执行 SetFunctionName (func ,
name , prefix )。
返回 func 。
本规范中定义的每个内置函数都是通过调用CreateBuiltinFunction抽象操作创建的。
10.4 内置异质对象内部方法和插槽
本规范定义了几种内置异质对象 。这些对象通常表现得像普通对象 ,除了一些特定情况。以下异质对象 使用普通对象 的内部方法,除非在下面明确指定了其他方法:
10.4.1 绑定函数异质对象
绑定函数异质对象 是一个异质对象 ,它包装另一个函数对象 。绑定函数异质对象 是可调用的(它有[[Call]] 内部方法,可能有[[Construct]] 内部方法)。调用绑定函数异质对象 通常会调用其包装的函数。
如果对象的[[Call]] 和(如果适用)[[Construct]] 内部方法使用以下实现,其他基本内部方法使用10.1 中的定义,则该对象是绑定函数异质对象 。这些方法在BoundFunctionCreate 中安装。
绑定函数异质对象 没有表30 中列出的ECMAScript函数对象 的内部插槽。相反,除了[[Prototype]] 和[[Extensible]] 之外,它们还有表31 中列出的内部插槽。
表31:绑定函数异质对象的内部插槽
内部插槽
类型
描述
[[BoundTargetFunction]]
可调用对象
被包装的函数对象 。
[[BoundThis]]
ECMAScript语言值
调用包装函数时总是作为this 值传递的值。
[[BoundArguments]]
ECMAScript语言值 的列表
一个值列表,其元素用作对包装函数的任何调用的前几个参数。
10.4.1.1 [[Call]] (
thisArgument , argumentsList )
绑定函数异质对象 F 的[[Call]] 内部方法接受参数thisArgument (ECMAScript语言值 )和argumentsList (ECMAScript语言值 的列表 ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
令 target 为 F .[[BoundTargetFunction]] 。
令 boundThis 为 F .[[BoundThis]] 。
令 boundArgs 为 F .[[BoundArguments]] 。
令 args 为 boundArgs 和 argumentsList 的列表连接 。
返回 ? Call (target ,
boundThis , args )。
10.4.1.2 [[Construct]] (
argumentsList , newTarget )
绑定函数异质对象 F 的[[Construct]] 内部方法接受参数argumentsList (ECMAScript语言值 的列表 )和newTarget (构造器 ),返回包含 对象的正常完成 或抛出完成 。调用时执行以下步骤:
令 target 为 F .[[BoundTargetFunction]] 。
断言 :IsConstructor (target ) 为
true 。
令 boundArgs 为 F .[[BoundArguments]] 。
令 args 为 boundArgs 和 argumentsList 的列表连接 。
如果 SameValue (F ,
newTarget ) 为 true ,设置 newTarget 为
target 。
返回 ? Construct (target ,
args , newTarget )。
10.4.1.3 BoundFunctionCreate ( targetFunction ,
boundThis , boundArgs )
抽象操作BoundFunctionCreate接受参数targetFunction (函数对象 )、boundThis (ECMAScript语言值 )和boundArgs (ECMAScript语言值 的列表 ),返回包含 函数对象 的正常完成 或抛出完成 。它用于指定新绑定函数异质对象 的创建。调用时执行以下步骤:
令 proto 为 ? targetFunction .[[GetPrototypeOf]] ()。
令 internalSlotsList 为 « [[Prototype]] , [[Extensible]] » 和表31 中列出的内部插槽的列表连接 。
令 obj 为 MakeBasicObject (internalSlotsList )。
设置 obj .[[Prototype]] 为 proto 。
按照10.4.1.1 中的描述设置
obj .[[Call]] 。
如果 IsConstructor (targetFunction )
为 true ,那么
按照10.4.1.2 中的描述设置
obj .[[Construct]] 。
设置 obj .[[BoundTargetFunction]] 为
targetFunction 。
设置 obj .[[BoundThis]] 为 boundThis 。
设置 obj .[[BoundArguments]] 为
boundArgs 。
返回 obj 。
10.4.2 数组异质对象
数组是一个异质对象 ,它对数组索引 属性键 给予特殊处理(见6.1.7 )。属性名 是数组索引 的属性也称为元素 。每个数组都有一个不可配置的"length" 属性,其值始终是非负整数 ,其数学值 严格小于232 。"length" 属性的值在数值上大于名称为数组索引 的每个自有属性的名称;每当创建或更改数组的自有属性时,会根据需要调整其他属性以维持此不变性。具体来说,每当添加名称为数组索引 的自有属性时,如有必要,"length" 属性的值会更改为该数组索引 的数值加一;每当"length" 属性的值更改时,名称为数组索引 且值不小于新长度的每个自有属性都会被删除。此约束仅适用于数组的自有属性,不受可能从其原型继承的"length" 或数组索引 属性的影响。
如果对象的[[DefineOwnProperty]] 内部方法使用以下实现,其他基本内部方法使用10.1 中的定义,则该对象是数组异质对象 (或简称数组)。这些方法在ArrayCreate 中安装。
10.4.2.1 [[DefineOwnProperty]] (
P , Desc )
数组异质对象 A 的[[DefineOwnProperty]] 内部方法接受参数P (属性键 )和Desc (属性描述符 ),返回包含 布尔值的正常完成 或抛出完成 。调用时执行以下步骤:
如果 P 是 "length" ,那么
返回 ? ArraySetLength (A ,
Desc )。
否则,如果 P 是数组索引 ,那么
令 lengthDesc 为 OrdinaryGetOwnProperty (A ,
"length" )。
断言 :lengthDesc 不是
undefined 。
断言 :IsDataDescriptor (lengthDesc )
为 true 。
断言 :lengthDesc .[[Configurable]] 为 false 。
令 length 为 lengthDesc .[[Value]] 。
断言 :length 是非负整数 。
令 index 为 ! ToUint32 (P )。
如果 index ≥ length 且 lengthDesc .[[Writable]] 为 false ,返回
false 。
令 succeeded 为 ! OrdinaryDefineOwnProperty (A ,
P , Desc )。
如果 succeeded 为 false ,返回
false 。
如果 index ≥ length ,那么
设置 lengthDesc .[[Value]] 为
index + 1 𝔽 。
设置 succeeded 为 ! OrdinaryDefineOwnProperty (A ,
"length" , lengthDesc )。
断言 :succeeded 为
true 。
返回 true 。
返回 ? OrdinaryDefineOwnProperty (A ,
P , Desc )。
10.4.2.2 ArrayCreate ( length [ , proto ]
)
抽象操作ArrayCreate接受参数length (非负整数 )和可选参数proto (对象),返回包含 数组异质对象 的正常完成 或抛出完成 。它用于指定新数组的创建。调用时执行以下步骤:
如果 length > 232 - 1,抛出 RangeError 异常。
如果 proto 不存在,设置 proto 为 %Array.prototype% 。
令 A 为 MakeBasicObject (« [[Prototype]] , [[Extensible]] »)。
设置 A .[[Prototype]] 为 proto 。
按照10.4.2.1 中指定的设置
A .[[DefineOwnProperty]] 。
执行 ! OrdinaryDefineOwnProperty (A ,
"length" , PropertyDescriptor { [[Value]] : 𝔽 (length ), [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : false })。
返回 A 。
10.4.2.3 ArraySpeciesCreate ( originalArray ,
length )
抽象操作ArraySpeciesCreate接受参数originalArray (对象)和length (非负整数 ),返回包含 对象的正常完成 或抛出完成 。它用于指定使用从originalArray 派生的构造器 函数创建新数组或类似对象。它不强制构造器 函数返回数组。调用时执行以下步骤:
令 isArray 为 ? IsArray (originalArray )。
如果 isArray 为 false ,返回 ? ArrayCreate (length )。
令 C 为 ? Get (originalArray ,
"constructor" )。
如果 IsConstructor (C ) 为
true ,那么
令 thisRealm 为 当前领域记录 。
令 realmC 为 ? GetFunctionRealm (C )。
如果 thisRealm 和 realmC 不是同一个领域记录 ,那么
如果 SameValue (C ,
realmC .[[Intrinsics]] .[[%Array% ]]) 为
true ,设置 C 为
undefined 。
如果 C 是对象 ,那么
设置 C 为 ? Get (C , %Symbol.species% )。
如果 C 为 null ,设置 C 为
undefined 。
如果 C 为 undefined ,返回 ? ArrayCreate (length )。
如果 IsConstructor (C ) 为
false ,抛出 TypeError 异常。
返回 ? Construct (C , « 𝔽 (length ) »)。
注
如果originalArray 是使用不是运行执行上下文 的领域 的领域 的标准内置数组构造器 创建的,那么使用运行执行上下文 的领域 创建新数组。这与Web浏览器的历史行为保持兼容,这些浏览器历史上对现在使用ArraySpeciesCreate定义的Array.prototype方法有这种行为。
10.4.2.4 ArraySetLength ( A , Desc )
抽象操作ArraySetLength接受参数A (数组)和Desc (属性描述符 ),返回包含 布尔值的正常完成 或抛出完成 。调用时执行以下步骤:
如果 Desc 没有 [[Value]] 字段,那么
返回 ! OrdinaryDefineOwnProperty (A ,
"length" , Desc )。
令 newLenDesc 为 Desc 的副本。
令 newLen 为 ? ToUint32 (Desc .[[Value]] )。
令 numberLen 为 ? ToNumber (Desc .[[Value]] )。
如果 SameValueZero (newLen ,
numberLen ) 为 false ,抛出 RangeError
异常。
设置 newLenDesc .[[Value]] 为 newLen 。
令 oldLenDesc 为 OrdinaryGetOwnProperty (A ,
"length" )。
断言 :oldLenDesc 不是
undefined 。
断言 :IsDataDescriptor (oldLenDesc )
为 true 。
断言 :oldLenDesc .[[Configurable]] 为 false 。
令 oldLen 为 oldLenDesc .[[Value]] 。
如果 newLen ≥ oldLen ,那么
返回 ! OrdinaryDefineOwnProperty (A ,
"length" , newLenDesc )。
如果 oldLenDesc .[[Writable]] 为
false ,返回 false 。
如果 newLenDesc 没有 [[Writable]] 字段或
newLenDesc .[[Writable]] 为
true ,那么
令 newWritable 为 true 。
否则,
注:如果任何元素无法删除,将[[Writable]] 属性设置为false 会被延迟。
令 newWritable 为 false 。
设置 newLenDesc .[[Writable]] 为
true 。
令 succeeded 为 ! OrdinaryDefineOwnProperty (A ,
"length" , newLenDesc )。
如果 succeeded 为 false ,返回 false 。
对于 A 的每个自有属性键 P ,如果 P
是数组索引 且 ! ToUint32 (P ) ≥
newLen ,按数值索引降序执行
令 deleteSucceeded 为 ! A .[[Delete]] (P )。
如果 deleteSucceeded 为 false ,那么
设置 newLenDesc .[[Value]] 为
! ToUint32 (P ) +
1 𝔽 。
如果 newWritable 为 false ,设置
newLenDesc .[[Writable]] 为
false 。
执行 ! OrdinaryDefineOwnProperty (A ,
"length" , newLenDesc )。
返回 false 。
如果 newWritable 为 false ,那么
设置 succeeded 为 ! OrdinaryDefineOwnProperty (A ,
"length" , PropertyDescriptor { [[Writable]] : false })。
断言 :succeeded 为
true 。
返回 true 。
注
在步骤3 和4 中,如果Desc .[[Value]] 是对象,则其valueOf方法会被调用两次。这是传统行为,从本规范第2版开始就以此效果进行了指定。
10.4.3 字符串异质对象
字符串对象是一个异质对象 ,它封装一个字符串值并暴露对应于字符串值各个码元元素的虚拟整数索引的 数据属性 。字符串异质对象 总是有一个名为"length" 的数据属性 ,其值是封装的字符串值的长度。码元数据属性 和"length" 属性都是不可写和不可配置的。
如果对象的[[GetOwnProperty]] 、[[DefineOwnProperty]] 和[[OwnPropertyKeys]] 内部方法使用以下实现,其他基本内部方法使用10.1 中的定义,则该对象是字符串异质对象 (或简称字符串对象)。这些方法在StringCreate 中安装。
字符串异质对象 具有与普通对象 相同的内部插槽。它们还有一个[[StringData]] 内部插槽。
10.4.3.1 [[GetOwnProperty]] (
P )
字符串异质对象 S 的[[GetOwnProperty]] 内部方法接受参数P (属性键 ),返回包含 属性描述符 或undefined 的正常完成 。调用时执行以下步骤:
令 desc 为 OrdinaryGetOwnProperty (S ,
P )。
如果 desc 不是 undefined ,返回 desc 。
返回 StringGetOwnProperty (S ,
P )。
10.4.3.2 [[DefineOwnProperty]] (
P , Desc )
字符串异质对象 S 的[[DefineOwnProperty]] 内部方法接受参数P (属性键 )和Desc (属性描述符 ),返回包含 布尔值的正常完成 。调用时执行以下步骤:
令 stringDesc 为 StringGetOwnProperty (S ,
P )。
如果 stringDesc 不是 undefined ,那么
令 extensible 为 S .[[Extensible]] 。
返回 IsCompatiblePropertyDescriptor (extensible ,
Desc , stringDesc )。
返回 ! OrdinaryDefineOwnProperty (S ,
P , Desc )。
10.4.3.3 [[OwnPropertyKeys]] ( )
字符串异质对象 O 的[[OwnPropertyKeys]] 内部方法不接受参数,返回包含 属性键 的列表 的正常完成 。调用时执行以下步骤:
令 keys 为新的空列表 。
令 str 为 O .[[StringData]] 。
断言 :str 是字符串 。
令 len 为 str 的长度。
对于每个整数
i ,0 ≤ i < len ,按升序执行
将 ! ToString (𝔽 (i )) 追加到
keys 。
对于 O 的每个自有属性键 P ,如果 P
是数组索引 且 ! ToIntegerOrInfinity (P )
≥ len ,按数值索引升序执行
将 P 追加到 keys 。
对于 O 的每个自有属性键 P ,如果 P
是字符串 且
P 不是数组索引 ,按属性创建的时间升序执行
将 P 追加到 keys 。
对于 O 的每个自有属性键 P ,如果 P
是Symbol ,按属性创建的时间升序执行
将 P 追加到 keys 。
返回 keys 。
10.4.3.4 StringCreate ( value , prototype )
抽象操作StringCreate接受参数value (字符串)和prototype (对象),返回字符串异质对象 。它用于指定新字符串异质对象 的创建。调用时执行以下步骤:
令 S 为 MakeBasicObject (« [[Prototype]] , [[Extensible]] , [[StringData]] »)。
设置 S .[[Prototype]] 为 prototype 。
设置 S .[[StringData]] 为 value 。
按照10.4.3.1 中指定的设置
S .[[GetOwnProperty]] 。
按照10.4.3.2 中指定的设置
S .[[DefineOwnProperty]] 。
按照10.4.3.3 中指定的设置
S .[[OwnPropertyKeys]] 。
令 length 为 value 的长度。
执行 ! DefinePropertyOrThrow (S ,
"length" , PropertyDescriptor { [[Value]] : 𝔽 (length ), [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false })。
返回 S 。
10.4.3.5 StringGetOwnProperty ( S , P )
抽象操作StringGetOwnProperty接受参数S (具有[[StringData]] 内部插槽的对象)和P (属性键 ),返回属性描述符 或undefined 。调用时执行以下步骤:
如果 P 不是字符串 ,返回
undefined 。
令 index 为 CanonicalNumericIndexString (P )。
如果 index 不是整数 ,返回 undefined 。
如果 index 是 -0 𝔽 或 index <
-0 𝔽 ,返回 undefined 。
令 str 为 S .[[StringData]] 。
断言 :str 是字符串 。
令 len 为 str 的长度。
如果 ℝ (index )
≥ len ,返回 undefined 。
令 resultStr 为 str 从 ℝ (index ) 到 ℝ (index ) + 1 的子字符串 。
返回 PropertyDescriptor { [[Value]] : resultStr ,
[[Writable]] : false , [[Enumerable]] : true , [[Configurable]] : false }。
10.4.4 Arguments 异质对象
大多数ECMAScript函数向其代码提供一个arguments对象。根据函数定义的特征,其arguments对象要么是普通对象 ,要么是arguments异质对象 。Arguments异质对象 是一个异质对象 ,其数组索引 属性映射到其关联ECMAScript函数调用的形式参数绑定。
如果对象的内部方法使用以下实现,其他未在此指定的方法使用10.1 中的实现,则该对象是arguments异质对象 。这些方法在CreateMappedArgumentsObject 中安装。
注1
Arguments异质对象 具有与普通对象 相同的内部插槽。它们还有一个[[ParameterMap]] 内部插槽。普通arguments对象也有一个[[ParameterMap]] 内部插槽,其值始终是undefined 。对于普通argument对象,[[ParameterMap]] 内部插槽仅被Object.prototype.toString(20.1.3.6 )用于识别它们。
注2
Arguments异质对象 的整数索引的 数据属性 ,其数值名称值小于对应函数对象 的形式参数数量,最初与函数执行上下文 中对应的参数绑定共享其值。这意味着更改属性会更改参数绑定的对应值,反之亦然。如果删除然后重新定义此类属性,或者将属性更改为访问器属性 ,则此对应关系会被破坏。如果arguments对象是普通对象 ,其属性值只是传递给函数的参数的副本,属性值与形式参数值之间没有动态链接。
注3
ParameterMap对象及其属性值被用作指定arguments对象与参数绑定对应关系的设备。ParameterMap对象和作为其属性值的对象不能从ECMAScript代码中直接观察到。ECMAScript实现不需要实际创建或使用此类对象来实现指定的语义。
注4
普通arguments对象定义一个名为"callee" 的不可配置访问器属性 ,访问时抛出TypeError 异常。"callee" 属性对于arguments异质对象 有更具体的含义,这些对象仅为某些类别的非严格函数 创建。在普通变体中定义此属性是为了确保符合标准的ECMAScript实现不会以任何其他方式定义它。
注5
Arguments异质对象 的ECMAScript实现历史上包含一个名为"caller" 的访问器属性 。在ECMAScript
2017之前,本规范包括在普通arguments对象上定义抛出"caller" 属性的定义。由于实现不再包含此扩展,ECMAScript
2017放弃了对抛出"caller" 访问器的要求。
10.4.4.1 [[GetOwnProperty]] (
P )
Arguments异质对象 args 的[[GetOwnProperty]] 内部方法接受参数P (属性键 ),返回包含 属性描述符 或undefined 的正常完成 。调用时执行以下步骤:
令 desc 为 OrdinaryGetOwnProperty (args ,
P )。
如果 desc 是 undefined ,返回 undefined 。
令 map 为 args .[[ParameterMap]] 。
令 isMapped 为 ! HasOwnProperty (map ,
P )。
如果 isMapped 为 true ,那么
设置 desc .[[Value]] 为 ! Get (map ,
P )。
返回 desc 。
10.4.4.2 [[DefineOwnProperty]] (
P , Desc )
Arguments异质对象 args 的[[DefineOwnProperty]] 内部方法接受参数P (属性键 )和Desc (属性描述符 ),返回包含 布尔值的正常完成 。调用时执行以下步骤:
令 map 为 args .[[ParameterMap]] 。
令 isMapped 为 ! HasOwnProperty (map ,
P )。
令 newArgDesc 为 Desc 。
如果 isMapped 为 true 且 IsDataDescriptor (Desc )
为 true ,那么
如果 Desc 没有 [[Value]] 字段,Desc
有 [[Writable]] 字段,且 Desc .[[Writable]] 为 false ,那么
设置 newArgDesc 为 Desc 的副本。
设置 newArgDesc .[[Value]] 为
! Get (map ,
P )。
令 allowed 为 ! OrdinaryDefineOwnProperty (args ,
P , newArgDesc )。
如果 allowed 为 false ,返回 false 。
如果 isMapped 为 true ,那么
如果 IsAccessorDescriptor (Desc )
为 true ,那么
执行 ! map .[[Delete]] (P )。
否则,
如果 Desc 有 [[Value]] 字段,那么
断言 :以下Set将成功,因为由arguments对象映射的形式参数总是可写的。
执行 ! Set (map ,
P , Desc .[[Value]] ,
false )。
如果 Desc 有 [[Writable]] 字段且
Desc .[[Writable]] 为
false ,那么
执行 ! map .[[Delete]] (P )。
返回 true 。
10.4.4.3 [[Get]] ( P ,
Receiver )
Arguments异质对象 args 的[[Get]] 内部方法接受参数P (属性键 )和Receiver (ECMAScript语言值 ),返回包含 ECMAScript语言值 的正常完成 或抛出完成 。调用时执行以下步骤:
令 map 为 args .[[ParameterMap]] 。
令 isMapped 为 ! HasOwnProperty (map ,
P )。
如果 isMapped 为 false ,那么
返回 ? OrdinaryGet (args ,
P , Receiver )。
否则,
断言 :map 包含 P
的形式参数映射。
返回 ! Get (map ,
P )。
10.4.4.4 [[Set]] ( P ,
V , Receiver )
Arguments异质对象 args 的[[Set]] 内部方法接受参数P (属性键 )、V (ECMAScript语言值 )和Receiver (ECMAScript语言值 ),返回包含 布尔值的正常完成 或抛出完成 。调用时执行以下步骤:
如果 SameValue (args ,
Receiver ) 为 false ,那么
令 isMapped 为 false 。
否则,
令 map 为 args .[[ParameterMap]] 。
令 isMapped 为 ! HasOwnProperty (map ,
P )。
如果 isMapped 为 true ,那么
断言 :以下Set将成功,因为由arguments对象映射的形式参数总是可写的。
执行 ! Set (map ,
P , V , false )。
返回 ? OrdinarySet (args ,
P , V , Receiver )。
10.4.4.5 [[Delete]] ( P )
Arguments异质对象 args 的[[Delete]] 内部方法接受参数P (属性键 ),返回包含 布尔值的正常完成 或抛出完成 。调用时执行以下步骤:
令 map 为 args .[[ParameterMap]] 。
令 isMapped 为 ! HasOwnProperty (map ,
P )。
令 result 为 ? OrdinaryDelete (args ,
P )。
如果 result 为 true 且 isMapped 为
true ,那么
执行 ! map .[[Delete]] (P )。
返回 result 。
10.4.4.6 CreateUnmappedArgumentsObject (
argumentsList )
抽象操作CreateUnmappedArgumentsObject接受参数argumentsList (ECMAScript语言值 的列表 ),返回普通对象 。调用时执行以下步骤:
令 len 为 argumentsList 中元素的数量。
令 obj 为 OrdinaryObjectCreate (%Object.prototype% ,
« [[ParameterMap]] »)。
设置 obj .[[ParameterMap]] 为
undefined 。
执行 ! DefinePropertyOrThrow (obj ,
"length" , PropertyDescriptor { [[Value]] : 𝔽 (len ), [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : true })。
令 index 为 0。
重复,当 index < len 时,
令 val 为 argumentsList [index ]。
执行 ! CreateDataPropertyOrThrow (obj ,
! ToString (𝔽 (index )),
val )。
设置 index 为 index + 1。
执行 ! DefinePropertyOrThrow (obj ,
%Symbol.iterator% ,
PropertyDescriptor { [[Value]] : %Array.prototype.values%,
[[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : true })。
执行 ! DefinePropertyOrThrow (obj ,
"callee" , PropertyDescriptor { [[Get]] :
%ThrowTypeError% , [[Set]] : %ThrowTypeError% ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 obj 。
10.4.4.7 CreateMappedArgumentsObject ( func ,
formals , argumentsList , env )
抽象操作CreateMappedArgumentsObject接受参数func (对象)、formals (解析节点 )、argumentsList (ECMAScript语言值 的列表 )和env (环境记录 ),返回arguments异质对象 。调用时执行以下步骤:
断言 :formals
不包含剩余参数、任何绑定模式或任何初始化器。它可能包含重复标识符。
令 len 为 argumentsList 中元素的数量。
令 obj 为 MakeBasicObject (« [[Prototype]] , [[Extensible]] , [[ParameterMap]] »)。
按照10.4.4.1 中指定的设置
obj .[[GetOwnProperty]] 。
按照10.4.4.2 中指定的设置
obj .[[DefineOwnProperty]] 。
按照10.4.4.3 中指定的设置
obj .[[Get]] 。
按照10.4.4.4 中指定的设置
obj .[[Set]] 。
按照10.4.4.5 中指定的设置
obj .[[Delete]] 。
设置 obj .[[Prototype]] 为 %Object.prototype% 。
令 map 为 OrdinaryObjectCreate (null )。
设置 obj .[[ParameterMap]] 为 map 。
令 parameterNames 为 formals 的BoundNames 。
令 numberOfParameters 为 parameterNames 中元素的数量。
令 index 为 0。
重复,当 index < len 时,
令 val 为 argumentsList [index ]。
执行 ! CreateDataPropertyOrThrow (obj ,
! ToString (𝔽 (index )),
val )。
设置 index 为 index + 1。
执行 ! DefinePropertyOrThrow (obj ,
"length" , PropertyDescriptor { [[Value]] : 𝔽 (len ), [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : true })。
令 mappedNames 为新的空列表 。
设置 index 为 numberOfParameters - 1。
重复,当 index ≥ 0 时,
令 name 为 parameterNames [index ]。
如果 mappedNames 不包含 name ,那么
将 name 追加到 mappedNames 。
如果 index < len ,那么
令 g 为 MakeArgGetter (name ,
env )。
令 p 为 MakeArgSetter (name ,
env )。
执行 ! map .[[DefineOwnProperty]] (! ToString (𝔽 (index )),
PropertyDescriptor { [[Set]] :
p , [[Get]] :
g , [[Enumerable]] :
false , [[Configurable]] :
true })。
设置 index 为 index - 1。
执行 ! DefinePropertyOrThrow (obj ,
%Symbol.iterator% ,
PropertyDescriptor { [[Value]] : %Array.prototype.values%,
[[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : true })。
执行 ! DefinePropertyOrThrow (obj ,
"callee" , PropertyDescriptor { [[Value]] : func , [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : true })。
返回 obj 。
10.4.4.7.1 MakeArgGetter ( name , env )
抽象操作MakeArgGetter接受参数name (字符串)和env (环境记录 ),返回函数对象 。它创建一个内置函数对象 ,执行时返回在env 中为name 绑定的值。调用时执行以下步骤:
令 getterClosure 为新的抽象闭包 ,没有参数,捕获name 和env ,调用时执行以下步骤:
返回 env .GetBindingValue(name ,
false )。
令 getter 为 CreateBuiltinFunction (getterClosure ,
0, "" , « »)。
注:getter 从不直接被ECMAScript代码访问。
返回 getter 。
10.4.4.7.2 MakeArgSetter ( name , env )
抽象操作MakeArgSetter接受参数name (字符串)和env (环境记录 ),返回函数对象 。它创建一个内置函数对象 ,执行时在env 中为name 设置绑定的值。调用时执行以下步骤:
令 setterClosure 为新的抽象闭包 ,参数为(value ),捕获name 和env ,调用时执行以下步骤:
返回 ! env .SetMutableBinding(name ,
value , false )。
令 setter 为 CreateBuiltinFunction (setterClosure ,
1, "" , « »)。
注:setter 从不直接被ECMAScript代码访问。
返回 setter 。
10.4.5 TypedArray 异质对象
TypedArray 是一个
异质对象 ,它对作为
规范数字字符串 的 属性键 执行特殊处理,使用界内的
整数索引
子集来索引统一类型的元素,并强制执行其余部分不存在且不引起原型链遍历的不变性。
注
因为对于任何数字 n ,ToString (n ) 都是一个 规范数字字符串 ,实现可以将数字视为
属性键
用于 TypedArrays ,而无需实际执行字符串转换。
TypedArrays 除了与
普通对象
相同的内部插槽外,还有 [[ViewedArrayBuffer]] 、[[ArrayLength]] 、[[ByteOffset]] 、[[ContentType]] 和 [[TypedArrayName]] 内部插槽。
如果一个对象的 [[PreventExtensions]] 、[[GetOwnProperty]] 、[[HasProperty]] 、[[DefineOwnProperty]] 、[[Get]] 、[[Set]] 、[[Delete]] 和 [[OwnPropertyKeys]] 内部方法使用本节中的定义,并且其他基本内部方法使用
10.1
中找到的定义,则该对象是一个 TypedArray 。这些方法由 TypedArrayCreate 安装。
10.4.5.1 [[PreventExtensions]] ( )
TypedArray
O 的 [[PreventExtensions]] 内部方法不接受参数并返回一个
包含
布尔值的正常完成。它在被调用时执行以下步骤:
注:6.1.7.3
中指定的可扩展性相关的不变性不允许此方法在 O 可以获得(或失去然后重新获得)属性时返回
true ,这可能发生在当其底层缓冲区被调整大小时具有 整数索引 名称的属性上。
如果 IsTypedArrayFixedLength (O )
是 false ,返回 false 。
返回 OrdinaryPreventExtensions (O )。
10.4.5.2 [[GetOwnProperty]] (
P )
TypedArray
O 的 [[GetOwnProperty]] 内部方法接受参数 P (一个
属性键 )并返回一个 包含 属性描述符 或
undefined 的正常完成。它在被调用时执行以下步骤:
如果 P 是一个字符串 ,那么
让 numericIndex 为 CanonicalNumericIndexString (P )。
如果 numericIndex 不是 undefined ,那么
让 value 为 TypedArrayGetElement (O ,
numericIndex )。
如果 value 是 undefined ,返回
undefined 。
返回属性描述符 { [[Value]] :
value ,[[Writable]] :
true ,[[Enumerable]] :
true ,[[Configurable]] :
true }。
返回 OrdinaryGetOwnProperty (O ,
P )。
10.4.5.3 [[HasProperty]] ( P
)
TypedArray
O 的 [[HasProperty]] 内部方法接受参数 P (一个 属性键 )并返回
包含 布尔值的正常完成或
抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个字符串 ,那么
让 numericIndex 为 CanonicalNumericIndexString (P )。
如果 numericIndex 不是 undefined ,返回
IsValidIntegerIndex (O ,
numericIndex )。
返回 ? OrdinaryHasProperty (O ,
P )。
10.4.5.4 [[DefineOwnProperty]] (
P , Desc )
TypedArray
O 的 [[DefineOwnProperty]] 内部方法接受参数 P (一个
属性键 )和
Desc (一个 属性描述符 )并返回
包含 布尔值的正常完成或
抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个字符串 ,那么
让 numericIndex 为 CanonicalNumericIndexString (P )。
如果 numericIndex 不是 undefined ,那么
如果 IsValidIntegerIndex (O ,
numericIndex ) 是 false ,返回
false 。
如果 Desc 有一个 [[Configurable]]
字段且 Desc .[[Configurable]]
是 false ,返回 false 。
如果 Desc 有一个 [[Enumerable]]
字段且 Desc .[[Enumerable]] 是
false ,返回 false 。
如果 IsAccessorDescriptor (Desc )
是 true ,返回 false 。
如果 Desc 有一个 [[Writable]] 字段
且 Desc .[[Writable]] 是
false ,返回 false 。
如果 Desc 有一个 [[Value]] 字段,
执行 ? TypedArraySetElement (O ,
numericIndex , Desc .[[Value]] )。
返回 true 。
返回 ! OrdinaryDefineOwnProperty (O ,
P , Desc )。
10.4.5.5 [[Get]] ( P ,
Receiver )
TypedArray
O 的 [[Get]] 内部方法接受参数 P (一个 属性键 )和
Receiver (一个 ECMAScript 语言值 )并返回 包含 ECMAScript 语言值 的正常完成或 抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个字符串 ,那么
让 numericIndex 为 CanonicalNumericIndexString (P )。
如果 numericIndex 不是 undefined ,那么
返回 TypedArrayGetElement (O ,
numericIndex )。
返回 ? OrdinaryGet (O , P ,
Receiver )。
10.4.5.6 [[Set]] ( P ,
V , Receiver )
TypedArray
O 的 [[Set]] 内部方法接受参数 P (一个 属性键 )、V (一个 ECMAScript 语言值 )和
Receiver (一个 ECMAScript 语言值 )并返回 包含 布尔值的正常完成或
抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个字符串 ,那么
让 numericIndex 为 CanonicalNumericIndexString (P )。
如果 numericIndex 不是 undefined ,那么
如果 SameValue (O ,
Receiver ) 是 true ,那么
执行 ? TypedArraySetElement (O ,
numericIndex , V )。
返回 true 。
如果 IsValidIntegerIndex (O ,
numericIndex ) 是 false ,返回
true 。
返回 ? OrdinarySet (O , P ,
V , Receiver )。
10.4.5.7 [[Delete]] ( P )
TypedArray
O 的 [[Delete]] 内部方法接受参数 P (一个 属性键 )并返回
包含
布尔值的正常完成。它在被调用时执行以下步骤:
如果 P 是一个字符串 ,那么
让 numericIndex 为 CanonicalNumericIndexString (P )。
如果 numericIndex 不是 undefined ,那么
如果 IsValidIntegerIndex (O ,
numericIndex ) 是 false ,返回
true ;否则返回 false 。
返回 ! OrdinaryDelete (O ,
P )。
10.4.5.8 [[OwnPropertyKeys]] ( )
TypedArray
O 的 [[OwnPropertyKeys]] 内部方法不接受参数并返回 包含 属性键 的
列表 的正常完成。它在被调用时执行以下步骤:
让 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
让 keys 为一个新的空 列表 。
如果 IsTypedArrayOutOfBounds (taRecord )
是 false ,那么
让 length 为 TypedArrayLength (taRecord )。
对于每个满足 0 ≤ i < length 的 整数 i ,按升序,执行
将 ! ToString (𝔽 (i )) 追加到
keys 。
对于 O 的每个自己的 属性键 P ,使得 P
是一个字符串
且 P 不是一个 整数索引 ,按属性创建的升序时间顺序,执行
将 P 追加到 keys 。
对于 O 的每个自己的 属性键 P ,使得 P
是一个符号 ,按属性创建的升序时间顺序,执行
将 P 追加到 keys 。
返回 keys 。
10.4.5.9 TypedArray 带缓冲区见证记录
TypedArray
带缓冲区见证记录 是一个用于封装 TypedArray 以及所查看缓冲区的缓存字节长度的 记录 值。当所查看的缓冲区是
可增长的
SharedArrayBuffer 时,它用于帮助确保字节长度数据块的单个共享内存读取事件。
TypedArray 带缓冲区见证记录具有 表
32 中列出的字段。
表 32:TypedArray
带缓冲区见证记录 字段
字段名称
值
含义
[[Object]]
一个 TypedArray
其缓冲区字节长度被加载的 TypedArray 。
[[CachedBufferByteLength]]
一个非负 整数 或
detached
创建 记录
时对象的 [[ViewedArrayBuffer]] 的字节长度。
10.4.5.10 MakeTypedArrayWithBufferWitnessRecord (
obj , order )
抽象操作 MakeTypedArrayWithBufferWitnessRecord 接受参数 obj (一个 TypedArray )和
order (seq-cst 或 unordered )并返回一个
TypedArray
带缓冲区见证记录 。它在被调用时执行以下步骤:
让 buffer 为 obj .[[ViewedArrayBuffer]] 。
如果 IsDetachedBuffer (buffer )
是 true ,那么
让 byteLength 为 detached 。
否则,
让 byteLength 为 ArrayBufferByteLength (buffer ,
order )。
返回 TypedArray
带缓冲区见证记录 { [[Object]] :
obj , [[CachedBufferByteLength]] :
byteLength }。
10.4.5.11 TypedArrayCreate ( prototype )
抽象操作 TypedArrayCreate 接受参数 prototype (一个对象)并返回一个 TypedArray 。它用于指定新 TypedArrays
的创建。它在被调用时执行以下步骤:
让 internalSlotsList 为 « [[Prototype]] 、[[Extensible]] 、[[ViewedArrayBuffer]] 、[[TypedArrayName]] 、[[ContentType]] 、[[ByteLength]] 、
[[ByteOffset]] 、[[ArrayLength]] »。
让 A 为 MakeBasicObject (internalSlotsList )。
设置 A .[[PreventExtensions]] 如 10.4.5.1 中所指定。
设置 A .[[GetOwnProperty]] 如 10.4.5.2 中所指定。
设置 A .[[HasProperty]] 如 10.4.5.3 中所指定。
设置 A .[[DefineOwnProperty]] 如 10.4.5.4 中所指定。
设置 A .[[Get]] 如 10.4.5.5 中所指定。
设置 A .[[Set]] 如 10.4.5.6 中所指定。
设置 A .[[Delete]] 如 10.4.5.7 中所指定。
设置 A .[[OwnPropertyKeys]] 如 10.4.5.8 中所指定。
设置 A .[[Prototype]] 为 prototype 。
返回 A 。
10.4.5.12 TypedArrayByteLength ( taRecord )
抽象操作 TypedArrayByteLength 接受参数 taRecord (一个 TypedArray
带缓冲区见证记录 )并返回一个非负 整数 。它在被调用时执行以下步骤:
如果 IsTypedArrayOutOfBounds (taRecord )
是 true ,返回 0。
让 length 为 TypedArrayLength (taRecord )。
如果 length = 0,返回 0。
让 O 为 taRecord .[[Object]] 。
如果 O .[[ByteLength]] 不是
auto ,返回 O .[[ByteLength]] 。
让 elementSize 为 TypedArrayElementSize (O )。
返回 length × elementSize 。
10.4.5.13 TypedArrayLength ( taRecord )
抽象操作 TypedArrayLength 接受参数 taRecord (一个 TypedArray
带缓冲区见证记录 )并返回一个非负 整数 。它在被调用时执行以下步骤:
断言 :
IsTypedArrayOutOfBounds (taRecord )
是 false 。
让 O 为 taRecord .[[Object]] 。
如果 O .[[ArrayLength]] 不是
auto ,返回 O .[[ArrayLength]] 。
断言 :
IsFixedLengthArrayBuffer (O .[[ViewedArrayBuffer]] ) 是 false 。
让 byteOffset 为 O .[[ByteOffset]] 。
让 elementSize 为 TypedArrayElementSize (O )。
让 byteLength 为 taRecord .[[CachedBufferByteLength]] 。
断言 :
byteLength 不是 detached 。
返回 floor ((byteLength -
byteOffset ) / elementSize )。
10.4.5.14 IsTypedArrayOutOfBounds ( taRecord )
抽象操作 IsTypedArrayOutOfBounds 接受参数 taRecord (一个 TypedArray
带缓冲区见证记录 )并返回一个布尔值。它检查对象的任何数字属性是否引用了在底层缓冲区边界内不包含的索引处的值。它在被调用时执行以下步骤:
让 O 为 taRecord .[[Object]] 。
让 bufferByteLength 为 taRecord .[[CachedBufferByteLength]] 。
断言 :
IsDetachedBuffer (O .[[ViewedArrayBuffer]] ) 是 true 当且仅当
bufferByteLength 是 detached 。
如果 bufferByteLength 是 detached ,返回
true 。
让 byteOffsetStart 为 O .[[ByteOffset]] 。
如果 O .[[ArrayLength]] 是
auto ,那么
让 byteOffsetEnd 为 bufferByteLength 。
否则,
让 elementSize 为 TypedArrayElementSize (O )。
让 byteOffsetEnd 为 byteOffsetStart +
O .[[ArrayLength]] ×
elementSize 。
如果 byteOffsetStart > bufferByteLength 或
byteOffsetEnd > bufferByteLength ,返回
true 。
注:0长度的 TypedArrays 不被认为是越界的。
返回 false 。
10.4.5.15 IsTypedArrayFixedLength ( O )
抽象操作 IsTypedArrayFixedLength 接受参数 O (一个 TypedArray )并返回一个布尔值。它在被调用时执行以下步骤:
如果 O .[[ArrayLength]] 是
auto ,返回 false 。
让 buffer 为 O .[[ViewedArrayBuffer]] 。
如果 IsFixedLengthArrayBuffer (buffer )
是 false 且 IsSharedArrayBuffer (buffer )
是 false ,返回 false 。
返回 true 。
10.4.5.16 IsValidIntegerIndex ( O , index )
抽象操作 IsValidIntegerIndex 接受参数 O (一个 TypedArray )和
index (一个数字)并返回一个布尔值。它在被调用时执行以下步骤:
如果 IsDetachedBuffer (O .[[ViewedArrayBuffer]] ) 是 true ,返回
false 。
如果 index 不是一个 整数数字 ,返回 false 。
如果 index 是 -0 𝔽 或 index <
-0 𝔽 ,返回 false 。
让 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
unordered )。
注:当 O 的支持缓冲区是 可增长的
SharedArrayBuffer 时,边界检查不是同步操作。
如果 IsTypedArrayOutOfBounds (taRecord )
是 true ,返回 false 。
让 length 为 TypedArrayLength (taRecord )。
如果 ℝ (index )
≥ length ,返回 false 。
返回 true 。
10.4.5.17 TypedArrayGetElement ( O , index
)
抽象操作 TypedArrayGetElement 接受参数 O (一个 TypedArray )和 index (一个数字)并返回一个数字、一个
BigInt 或 undefined 。它在被调用时执行以下步骤:
如果 IsValidIntegerIndex (O ,
index ) 是 false ,返回 undefined 。
让 offset 为 O .[[ByteOffset]] 。
让 elementSize 为 TypedArrayElementSize (O )。
让 byteIndexInBuffer 为 (ℝ (index ) × elementSize ) +
offset 。
让 elementType 为 TypedArrayElementType (O )。
返回 GetValueFromBuffer (O .[[ViewedArrayBuffer]] , byteIndexInBuffer ,
elementType , true , unordered )。
10.4.5.18 TypedArraySetElement ( O , index ,
value )
抽象操作 TypedArraySetElement 接受参数 O (一个 TypedArray )、index (一个数字)和
value (一个 ECMAScript 语言值 )并返回 包含
unused 的正常完成或 抛出完成 。它在被调用时执行以下步骤:
如果 O .[[ContentType]] 是
bigint ,让 numValue 为 ? ToBigInt (value )。
否则,让 numValue 为 ? ToNumber (value )。
如果 IsValidIntegerIndex (O ,
index ) 是 true ,那么
让 offset 为 O .[[ByteOffset]] 。
让 elementSize 为 TypedArrayElementSize (O )。
让 byteIndexInBuffer 为 (ℝ (index ) ×
elementSize ) + offset 。
让 elementType 为 TypedArrayElementType (O )。
执行 SetValueInBuffer (O .[[ViewedArrayBuffer]] , byteIndexInBuffer ,
elementType , numValue , true ,
unordered )。
返回 unused 。
注
此操作总是显得成功,但是当尝试写入 TypedArray 的末尾之外或写入由分离的 ArrayBuffer 支持的
TypedArray 时,它没有效果。
10.4.5.19 IsArrayBufferViewOutOfBounds ( O )
抽象操作 IsArrayBufferViewOutOfBounds 接受参数 O (一个 TypedArray 或一个 DataView)并返回一个布尔值。它检查
TypedArray
的任何数字属性或 DataView 对象的方法是否可以引用在底层数据块边界内不包含的索引处的值。此抽象操作作为上游规范的便利而存在。它在被调用时执行以下步骤:
如果 O 有一个 [[DataView]] 内部插槽,那么
让 viewRecord 为 MakeDataViewWithBufferWitnessRecord (O ,
seq-cst )。
返回 IsViewOutOfBounds (viewRecord )。
让 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
返回 IsTypedArrayOutOfBounds (taRecord )。
10.4.6 模块命名空间异质对象
模块命名空间异质对象 是一个 异质对象 ,它暴露从
ECMAScript 模块 导出的绑定(参见 16.2.3 )。模块命名空间异质对象 的字符串键自己的属性与 模块 导出的绑定名称之间存在一对一的对应关系。导出的绑定包括使用
export * 导出项间接导出的任何绑定。每个字符串值自己的 属性键 是对应导出绑定名称的 StringValue 。这些是
模块命名空间异质对象 的唯一字符串键属性。每个这样的属性都具有属性
{ [[Writable]] : true 、[[Enumerable]] : true 、[[Configurable]] : false }。模块命名空间异质对象 是不可扩展的。
如果一个对象的 [[GetPrototypeOf]] 、[[SetPrototypeOf]] 、[[IsExtensible]] 、[[PreventExtensions]] 、[[GetOwnProperty]] 、[[DefineOwnProperty]] 、[[HasProperty]] 、[[Get]] 、[[Set]] 、[[Delete]] 和 [[OwnPropertyKeys]]
内部方法使用本节中的定义,并且其他基本内部方法使用 10.1
中找到的定义,则该对象是一个 模块命名空间异质对象 。这些方法由 ModuleNamespaceCreate 安装。
模块命名空间异质对象 具有 表 33
中定义的内部插槽。
表 33:模块命名空间异质对象的内部插槽
内部插槽
类型
描述
[[Module]]
一个 模块记录
此命名空间暴露其导出的 模块记录 。
[[Exports]]
一个字符串的 列表
一个 列表 ,其元素是作为此对象自己的属性暴露的导出名称的字符串值。该列表按
字典代码单元顺序 排序。
10.4.6.1 [[GetPrototypeOf]] ( )
模块命名空间异质对象 的 [[GetPrototypeOf]] 内部方法不接受参数并返回 包含
null 的正常完成。它在被调用时执行以下步骤:
返回 null 。
10.4.6.2 [[SetPrototypeOf]] (
V )
模块命名空间异质对象 O 的 [[SetPrototypeOf]] 内部方法接受参数 V (一个对象或
null )并返回 包含
布尔值的正常完成。它在被调用时执行以下步骤:
返回 ! SetImmutablePrototype (O ,
V )。
10.4.6.3 [[IsExtensible]] ( )
模块命名空间异质对象 的 [[IsExtensible]] 内部方法不接受参数并返回 包含
false 的正常完成。它在被调用时执行以下步骤:
返回 false 。
10.4.6.4 [[PreventExtensions]] ( )
模块命名空间异质对象 的 [[PreventExtensions]] 内部方法不接受参数并返回 包含
true 的正常完成。它在被调用时执行以下步骤:
返回 true 。
10.4.6.5 [[GetOwnProperty]] (
P )
模块命名空间异质对象 O 的 [[GetOwnProperty]] 内部方法接受参数 P (一个 属性键 )并返回
包含 属性描述符 或
undefined 的正常完成,或 抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个符号 ,返回
OrdinaryGetOwnProperty (O ,
P )。
让 exports 为 O .[[Exports]] 。
如果 exports 不包含 P ,返回 undefined 。
让 value 为 ? O .[[Get]] (P , O )。
返回属性描述符 { [[Value]] : value 、[[Writable]] : true 、[[Enumerable]] : true 、[[Configurable]] : false }。
10.4.6.6 [[DefineOwnProperty]] (
P , Desc )
模块命名空间异质对象 O 的 [[DefineOwnProperty]] 内部方法接受参数 P (一个 属性键 )和
Desc (一个 属性描述符 )并返回
包含 布尔值的正常完成或
抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个符号 ,返回
! OrdinaryDefineOwnProperty (O ,
P , Desc )。
让 current 为 ? O .[[GetOwnProperty]] (P )。
如果 current 是 undefined ,返回 false 。
如果 Desc 有一个 [[Configurable]] 字段且
Desc .[[Configurable]] 是
true ,返回 false 。
如果 Desc 有一个 [[Enumerable]] 字段且
Desc .[[Enumerable]] 是
false ,返回 false 。
如果 IsAccessorDescriptor (Desc )
是 true ,返回 false 。
如果 Desc 有一个 [[Writable]] 字段且
Desc .[[Writable]] 是 false ,返回
false 。
如果 Desc 有一个 [[Value]] 字段,返回 SameValue (Desc .[[Value]] , current .[[Value]] )。
返回 true 。
10.4.6.7 [[HasProperty]] ( P
)
模块命名空间异质对象 O 的 [[HasProperty]] 内部方法接受参数 P (一个 属性键 )并返回
包含
布尔值的正常完成。它在被调用时执行以下步骤:
如果 P 是一个符号 ,返回
! OrdinaryHasProperty (O ,
P )。
让 exports 为 O .[[Exports]] 。
如果 exports 包含 P ,返回 true 。
返回 false 。
10.4.6.8 [[Get]] ( P ,
Receiver )
模块命名空间异质对象 O 的 [[Get]] 内部方法接受参数 P (一个 属性键 )和 Receiver (一个
ECMAScript 语言值 )并返回 包含 ECMAScript 语言值 的正常完成或 抛出完成 。它在被调用时执行以下步骤:
如果 P 是一个符号 ,那么
返回 ! OrdinaryGet (O ,
P , Receiver )。
让 exports 为 O .[[Exports]] 。
如果 exports 不包含 P ,返回 undefined 。
让 m 为 O .[[Module]] 。
让 binding 为 m .ResolveExport(P )。
断言 :
binding 是一个 ResolvedBinding 记录 。
让 targetModule 为 binding .[[Module]] 。
断言 :
targetModule 不是 undefined 。
如果 binding .[[BindingName]] 是
namespace ,那么
返回 GetModuleNamespace (targetModule )。
让 targetEnv 为 targetModule .[[Environment]] 。
如果 targetEnv 是 empty ,抛出一个
ReferenceError 异常。
返回 ? targetEnv .GetBindingValue(binding .[[BindingName]] , true )。
注
ResolveExport 是无副作用的。每当使用特定的 exportName 、resolveSet
对作为参数调用此操作时,它必须返回相同的结果。实现可能选择预计算或缓存每个 模块命名空间异质对象 的 [[Exports]] 的 ResolveExport 结果。
10.4.6.9 [[Set]] ( P ,
V , Receiver )
模块命名空间异质对象 的 [[Set]] 内部方法接受参数 P (一个 属性键 )、V (一个 ECMAScript 语言值 )和
Receiver (一个 ECMAScript 语言值 )并返回 包含
false 的正常完成。它在被调用时执行以下步骤:
返回 false 。
10.4.6.10 [[Delete]] ( P )
模块命名空间异质对象 O 的 [[Delete]] 内部方法接受参数 P (一个 属性键 )并返回 包含
布尔值的正常完成。它在被调用时执行以下步骤:
如果 P 是一个符号 ,那么
返回 ! OrdinaryDelete (O ,
P )。
让 exports 为 O .[[Exports]] 。
如果 exports 包含 P ,返回 false 。
返回 true 。
10.4.6.11 [[OwnPropertyKeys]] ( )
模块命名空间异质对象 O 的 [[OwnPropertyKeys]] 内部方法不接受参数并返回 包含 属性键 的
列表 的正常完成。它在被调用时执行以下步骤:
让 exports 为 O .[[Exports]] 。
让 symbolKeys 为 OrdinaryOwnPropertyKeys (O )。
返回 exports 和 symbolKeys 的 列表连接 。
10.4.6.12 ModuleNamespaceCreate ( module ,
exports )
抽象操作 ModuleNamespaceCreate 接受参数 module (一个 模块记录 )和 exports (一个字符串的
列表 )并返回一个 模块命名空间异质对象 。它用于指定新 模块命名空间异质对象 的创建。它在被调用时执行以下步骤:
断言 :
module .[[Namespace]] 是
empty 。
让 internalSlotsList 为 表
33 中列出的内部插槽。
让 M 为 MakeBasicObject (internalSlotsList )。
设置 M 的基本内部方法为 10.4.6 中指定的定义。
设置 M .[[Module]] 为 module 。
让 sortedExports 为一个 列表 ,其元素是
exports 的元素,按 字典代码单元顺序
排序。
设置 M .[[Exports]] 为 sortedExports 。
创建 M 的自己的属性,对应于 28.3 中的定义。
设置 module .[[Namespace]] 为 M 。
返回 M 。
10.4.7 不可变原型异质对象
不可变原型异质对象 是一个 异质对象 ,它具有一个 [[Prototype]] 内部插槽,一旦初始化后就不会更改。
如果一个对象的 [[SetPrototypeOf]] 内部方法使用以下实现,则该对象是一个 不可变原型异质对象 。(其他基本内部方法可以使用任何实现,取决于所涉及的特定 不可变原型异质对象 。)
注
与其他 异质对象 不同,没有为 不可变原型异质对象
提供专门的创建抽象操作。这是因为它们仅被 %Object.prototype%
和 宿主环境 使用,而在 宿主环境 中,相关对象可能在其他方面也是异质的,因此需要它们自己的专门创建操作。
10.4.7.1 [[SetPrototypeOf]] (
V )
不可变原型异质对象 O 的
[[SetPrototypeOf]] 内部方法接受参数 V (一个对象或
null )并返回 包含
布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
返回 ? SetImmutablePrototype (O ,
V )。
10.4.7.2 SetImmutablePrototype ( O , V )
抽象操作 SetImmutablePrototype 接受参数 O (一个对象)和 V (一个对象或
null )并返回 包含
布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
让 current 为 ? O .[[GetPrototypeOf]] ()。
如果 SameValue (V ,
current ) 是 true ,返回 true 。
返回 false 。
10.5 代理对象内部方法和内部插槽
代理对象是一个 异质对象 ,其基本内部方法部分使用 ECMAScript 代码实现。每个代理对象都有一个名为 [[ProxyHandler]] 的内部插槽。[[ProxyHandler]]
的值是一个对象,称为代理的处理器对象 ,或者是 null 。处理器对象的方法(参见 表
34 )可用于增强代理对象一个或多个内部方法的实现。每个代理对象还有一个名为 [[ProxyTarget]] 的内部插槽,其值要么是一个对象,要么是
null 。这个对象称为代理的目标对象 。
如果一个对象的基本内部方法(包括 [[Call]] 和 [[Construct]] ,如果适用)使用本节中的定义,则该对象是一个 代理异质对象 。这些内部方法在 ProxyCreate 中安装。
表 34:代理处理器方法
内部方法
处理器方法
[[GetPrototypeOf]]
getPrototypeOf
[[SetPrototypeOf]]
setPrototypeOf
[[IsExtensible]]
isExtensible
[[PreventExtensions]]
preventExtensions
[[GetOwnProperty]]
getOwnPropertyDescriptor
[[DefineOwnProperty]]
defineProperty
[[HasProperty]]
has
[[Get]]
get
[[Set]]
set
[[Delete]]
deleteProperty
[[OwnPropertyKeys]]
ownKeys
[[Call]]
apply
[[Construct]]
construct
当调用处理器方法来提供代理对象内部方法的实现时,处理器方法将代理的目标对象作为参数传递。代理的处理器对象不一定具有与每个基本内部方法相对应的方法。如果处理器对象没有与内部陷阱相对应的方法,则在代理上调用内部方法会导致在代理的目标对象上调用相应的内部方法。
代理对象的 [[ProxyHandler]] 和 [[ProxyTarget]]
内部插槽在创建对象时总是被初始化,通常不能被修改。某些代理对象以允许它们随后被撤销 的方式创建。当代理被撤销时,其 [[ProxyHandler]] 和 [[ProxyTarget]] 内部插槽被设置为
null ,导致该代理对象上内部方法的后续调用抛出 TypeError 异常。
因为代理对象允许通过任意 ECMAScript 代码提供内部方法的实现,所以可以定义一个代理对象,其处理器方法违反了 6.1.7.3
中定义的不变量。6.1.7.3
中定义的一些内部方法不变量是基本的完整性不变量。这些不变量由本节中指定的代理对象内部方法显式强制执行。ECMAScript 实现必须在所有可能的不变量违反的情况下保持健壮。
在以下算法描述中,假设 O 是一个 ECMAScript 代理对象,P 是一个 属性键 值,V 是任何 ECMAScript 语言值 ,Desc 是一个
属性描述符 记录。
10.5.1 [[GetPrototypeOf]] ( )
代理异质对象 O 的 [[GetPrototypeOf]] 内部方法不接受参数并返回 包含 对象或
null 的正常完成,或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"getPrototypeOf" )。
如果 trap 是 undefined ,那么
返回 ? target .[[GetPrototypeOf]] ()。
让 handlerProto 为 ? Call (trap ,
handler , « target »)。
如果 handlerProto 不是一个对象 且 handlerProto 不是
null ,抛出一个 TypeError 异常。
让 extensibleTarget 为 ? IsExtensible (target )。
如果 extensibleTarget 是 true ,返回 handlerProto 。
让 targetProto 为 ? target .[[GetPrototypeOf]] ()。
如果 SameValue (handlerProto ,
targetProto ) 是 false ,抛出一个 TypeError 异常。
返回 handlerProto 。
注
代理对象的 [[GetPrototypeOf]] 强制执行以下不变量:
[[GetPrototypeOf]] 的结果必须是一个对象或 null 。
如果目标对象不可扩展,应用于代理对象的 [[GetPrototypeOf]] 必须返回与应用于代理对象的目标对象的
[[GetPrototypeOf]] 相同的值。
10.5.2 [[SetPrototypeOf]] ( V )
代理异质对象 O 的 [[SetPrototypeOf]] 内部方法接受参数 V (一个对象或
null )并返回 包含
布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"setPrototypeOf" )。
如果 trap 是 undefined ,那么
返回 ? target .[[SetPrototypeOf]] (V )。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target , V »))。
如果 booleanTrapResult 是 false ,返回 false 。
让 extensibleTarget 为 ? IsExtensible (target )。
如果 extensibleTarget 是 true ,返回 true 。
让 targetProto 为 ? target .[[GetPrototypeOf]] ()。
如果 SameValue (V ,
targetProto ) 是 false ,抛出一个 TypeError 异常。
返回 true 。
注
代理对象的 [[SetPrototypeOf]] 强制执行以下不变量:
[[SetPrototypeOf]] 的结果 是一个布尔值 。
如果目标对象不可扩展,参数值必须与应用于目标对象的 [[GetPrototypeOf]] 的结果相同。
10.5.3 [[IsExtensible]] ( )
代理异质对象 O 的 [[IsExtensible]] 内部方法不接受参数并返回 包含 布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"isExtensible" )。
如果 trap 是 undefined ,那么
返回 ? IsExtensible (target )。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target »))。
让 targetResult 为 ? IsExtensible (target )。
如果 booleanTrapResult 不是 targetResult ,抛出一个
TypeError 异常。
返回 booleanTrapResult 。
注
代理对象的 [[IsExtensible]] 强制执行以下不变量:
[[IsExtensible]] 的结果 是一个布尔值 。
应用于代理对象的 [[IsExtensible]] 必须返回与应用于代理对象的目标对象的 [[IsExtensible]] 相同的值。
10.5.4 [[PreventExtensions]] ( )
代理异质对象 O 的 [[PreventExtensions]] 内部方法不接受参数并返回 包含 布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"preventExtensions" )。
如果 trap 是 undefined ,那么
返回 ? target .[[PreventExtensions]] () 。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target »))。
如果 booleanTrapResult 是 true ,那么
让 extensibleTarget 为 ? IsExtensible (target )。
如果 extensibleTarget 是 true ,抛出一个
TypeError 异常。
返回 booleanTrapResult 。
注
代理对象的 [[PreventExtensions]] 强制执行以下不变量:
[[PreventExtensions]] 的结果 是一个布尔值 。
应用于代理对象的 [[PreventExtensions]] 仅在应用于代理对象的目标对象的 [[IsExtensible]] 为 false 时才返回
true 。
10.5.5 [[GetOwnProperty]] ( P )
代理异质对象 O 的 [[GetOwnProperty]] 内部方法接受参数 P (一个 属性键 )并返回 包含 属性描述符 或
undefined 的正常完成,或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"getOwnPropertyDescriptor" )。
如果 trap 是 undefined ,那么
返回 ? target .[[GetOwnProperty]] (P )。
让 trapResultObj 为 ? Call (trap ,
handler , « target , P »)。
如果 trapResultObj 不是一个对象 且 trapResultObj 不是
undefined ,抛出一个 TypeError 异常。
让 targetDesc 为 ? target .[[GetOwnProperty]] (P )。
如果 trapResultObj 是 undefined ,那么
如果 targetDesc 是 undefined ,返回
undefined 。
如果 targetDesc .[[Configurable]] 是
false ,抛出一个 TypeError 异常。
让 extensibleTarget 为 ? IsExtensible (target )。
如果 extensibleTarget 是 false ,抛出一个
TypeError 异常。
返回 undefined 。
让 extensibleTarget 为 ? IsExtensible (target )。
让 resultDesc 为 ? ToPropertyDescriptor (trapResultObj )。
执行 CompletePropertyDescriptor (resultDesc )。
让 valid 为 IsCompatiblePropertyDescriptor (extensibleTarget ,
resultDesc , targetDesc )。
如果 valid 是 false ,抛出一个 TypeError 异常。
如果 resultDesc .[[Configurable]] 是
false ,那么
如果 targetDesc 是 undefined 或
targetDesc .[[Configurable]] 是
true ,那么
抛出一个 TypeError 异常。
如果 resultDesc 有一个 [[Writable]] 字段且
resultDesc .[[Writable]] 是
false ,那么
断言 :targetDesc 有一个 [[Writable]] 字段。
如果 targetDesc .[[Writable]] 是
true ,抛出一个 TypeError 异常。
返回 resultDesc 。
注
代理对象的 [[GetOwnProperty]] 强制执行以下不变量:
[[GetOwnProperty]] 的结果必须是一个对象或
undefined 。
如果属性作为目标对象的不可配置自有属性存在,则不能报告该属性不存在。
如果属性作为不可扩展目标对象的自有属性存在,则不能报告该属性不存在。
如果属性不作为目标对象的自有属性存在且目标对象不可扩展,则不能报告该属性存在。
除非属性作为目标对象的不可配置自有属性存在,否则不能报告该属性为不可配置。
除非属性作为目标对象的不可配置、不可写自有属性存在,否则不能报告该属性既不可配置又不可写。
10.5.6 [[DefineOwnProperty]] (
P , Desc )
代理异质对象 O 的 [[DefineOwnProperty]] 内部方法接受参数 P (一个 属性键 )和
Desc (一个 属性描述符 )并返回 包含 布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"defineProperty" )。
如果 trap 是 undefined ,那么
返回 ? target .[[DefineOwnProperty]] (P ,
Desc )。
让 descObj 为 FromPropertyDescriptor (Desc )。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target , P , descObj »))。
如果 booleanTrapResult 是 false ,返回 false 。
让 targetDesc 为 ? target .[[GetOwnProperty]] (P )。
让 extensibleTarget 为 ? IsExtensible (target )。
如果 Desc 有一个 [[Configurable]] 字段且
Desc .[[Configurable]] 是 false ,那么
让 settingConfigFalse 为 true 。
否则,
让 settingConfigFalse 为 false 。
如果 targetDesc 是 undefined ,那么
如果 extensibleTarget 是 false ,抛出一个
TypeError 异常。
如果 settingConfigFalse 是 true ,抛出一个
TypeError 异常。
否则,
如果 IsCompatiblePropertyDescriptor (extensibleTarget ,
Desc , targetDesc ) 是 false ,抛出一个
TypeError 异常。
如果 settingConfigFalse 是 true 且
targetDesc .[[Configurable]] 是
true ,抛出一个 TypeError 异常。
如果 IsDataDescriptor (targetDesc )
是 true ,targetDesc .[[Configurable]] 是 false ,且
targetDesc .[[Writable]] 是
true ,那么
如果 Desc 有一个 [[Writable]] 字段且
Desc .[[Writable]] 是
false ,抛出一个 TypeError 异常。
返回 true 。
注
代理对象的 [[DefineOwnProperty]] 强制执行以下不变量:
[[DefineOwnProperty]] 的结果 是一个布尔值 。
如果目标对象不可扩展,则不能添加属性。
除非目标对象存在相应的不可配置自有属性,否则属性不能为不可配置。
除非目标对象存在相应的不可配置、不可写自有属性,否则不可配置属性不能为不可写。
如果属性有相应的目标对象属性,则使用 [[DefineOwnProperty]] 将该属性的 属性描述符
应用于目标对象不会抛出异常。
10.5.7 [[HasProperty]] ( P )
代理异质对象 O 的 [[HasProperty]] 内部方法接受参数 P (一个 属性键 )并返回 包含 布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"has" )。
如果 trap 是 undefined ,那么
返回 ? target .[[HasProperty]] (P )。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target , P »))。
如果 booleanTrapResult 是 false ,那么
让 targetDesc 为 ? target .[[GetOwnProperty]] (P )。
如果 targetDesc 不是 undefined ,那么
如果 targetDesc .[[Configurable]] 是
false ,抛出一个 TypeError 异常。
让 extensibleTarget 为 ? IsExtensible (target )。
如果 extensibleTarget 是 false ,抛出一个
TypeError 异常。
返回 booleanTrapResult 。
注
代理对象的 [[HasProperty]] 强制执行以下不变量:
[[HasProperty]] 的结果 是一个布尔值 。
如果属性作为目标对象的不可配置自有属性存在,则不能报告该属性不存在。
如果属性作为目标对象的自有属性存在且目标对象不可扩展,则不能报告该属性不存在。
10.5.8 [[Get]] ( P ,
Receiver )
代理异质对象 O 的 [[Get]] 内部方法接受参数 P (一个 属性键 )和 Receiver (一个 ECMAScript 语言值 )并返回 包含 ECMAScript 语言值 的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"get" )。
如果 trap 是 undefined ,那么
返回 ? target .[[Get]] (P , Receiver )。
让 trapResult 为 ? Call (trap ,
handler , « target , P , Receiver »)。
让 targetDesc 为 ? target .[[GetOwnProperty]] (P )。
如果 targetDesc 不是 undefined 且 targetDesc .[[Configurable]] 是 false ,那么
如果 IsDataDescriptor (targetDesc )
是 true 且 targetDesc .[[Writable]] 是 false ,那么
如果 SameValue (trapResult ,
targetDesc .[[Value]] ) 是
false ,抛出一个 TypeError 异常。
如果 IsAccessorDescriptor (targetDesc )
是 true 且 targetDesc .[[Get]] 是 undefined ,那么
如果 trapResult 不是 undefined ,抛出一个
TypeError 异常。
返回 trapResult 。
注
代理对象的 [[Get]] 强制执行以下不变量:
如果目标对象属性是不可写、不可配置的自有 数据属性 ,则为属性报告的值必须与相应目标对象属性的值相同。
如果相应的目标对象属性是不可配置的自有 访问器属性 ,且其 [[Get]] 特性为 undefined ,则为属性报告的值必须是
undefined 。
10.5.9 [[Set]] ( P ,
V , Receiver )
代理异质对象 O 的 [[Set]] 内部方法接受参数 P (一个 属性键 )、V (一个 ECMAScript 语言值 )和
Receiver (一个 ECMAScript 语言值 )并返回 包含 布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"set" )。
如果 trap 是 undefined ,那么
返回 ? target .[[Set]] (P , V ,
Receiver )。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target , P , V , Receiver »))。
如果 booleanTrapResult 是 false ,返回 false 。
让 targetDesc 为 ? target .[[GetOwnProperty]] (P )。
如果 targetDesc 不是 undefined 且 targetDesc .[[Configurable]] 是 false ,那么
如果 IsDataDescriptor (targetDesc )
是 true 且 targetDesc .[[Writable]] 是 false ,那么
如果 SameValue (V ,
targetDesc .[[Value]] ) 是
false ,抛出一个 TypeError 异常。
如果 IsAccessorDescriptor (targetDesc )
是 true ,那么
如果 targetDesc .[[Set]] 是
undefined ,抛出一个 TypeError 异常。
返回 true 。
注
代理对象的 [[Set]] 强制执行以下不变量:
[[Set]] 的结果 是一个布尔值 。
如果相应的目标对象属性是不可写、不可配置的自有 数据属性 ,则不能将属性的值更改为与相应目标对象属性的值不同。
如果相应的目标对象属性是不可配置的自有 访问器属性 ,且其 [[Set]] 特性为 undefined ,则不能设置属性的值。
10.5.10 [[Delete]] ( P )
代理异质对象 O 的 [[Delete]] 内部方法接受参数 P (一个 属性键 )并返回 包含 布尔值的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"deleteProperty" )。
如果 trap 是 undefined ,那么
返回 ? target .[[Delete]] (P )。
让 booleanTrapResult 为 ToBoolean (? Call (trap , handler , «
target , P »))。
如果 booleanTrapResult 是 false ,返回 false 。
让 targetDesc 为 ? target .[[GetOwnProperty]] (P )。
如果 targetDesc 是 undefined ,返回 true 。
如果 targetDesc .[[Configurable]] 是
false ,抛出一个 TypeError 异常。
让 extensibleTarget 为 ? IsExtensible (target )。
如果 extensibleTarget 是 false ,抛出一个
TypeError 异常。
返回 true 。
注
代理对象的 [[Delete]] 强制执行以下不变量:
[[Delete]] 的结果 是一个布尔值 。
如果属性作为目标对象的不可配置自有属性存在,则不能报告该属性被删除。
如果属性作为目标对象的自有属性存在且目标对象不可扩展,则不能报告该属性被删除。
10.5.11 [[OwnPropertyKeys]] ( )
代理异质对象 O 的 [[OwnPropertyKeys]] 内部方法不接受参数并返回 包含 列表 的正常完成(该列表包含 属性键 )或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"ownKeys" )。
如果 trap 是 undefined ,那么
返回 ? target .[[OwnPropertyKeys]] () 。
让 trapResultArray 为 ? Call (trap ,
handler , « target »)。
让 trapResult 为 ? CreateListFromArrayLike (trapResultArray ,
property-key )。
如果 trapResult 包含任何重复条目,抛出一个 TypeError 异常。
让 extensibleTarget 为 ? IsExtensible (target )。
让 targetKeys 为 ? target .[[OwnPropertyKeys]] () 。
断言 :
targetKeys 是一个包含 属性键 的 列表 。
断言 :
targetKeys 不包含重复条目。
让 targetConfigurableKeys 为一个新的空 列表 。
让 targetNonconfigurableKeys 为一个新的空 列表 。
对 targetKeys 的每个元素 key ,执行
让 desc 为 ? target .[[GetOwnProperty]] (key )。
如果 desc 不是 undefined 且 desc .[[Configurable]] 是 false ,那么
将 key 追加到 targetNonconfigurableKeys 。
否则,
将 key 追加到 targetConfigurableKeys 。
如果 extensibleTarget 是 true 且
targetNonconfigurableKeys 是空的,那么
返回 trapResult 。
让 uncheckedResultKeys 为一个 列表 ,其元素是
trapResult 的元素。
对 targetNonconfigurableKeys 的每个元素 key ,执行
如果 uncheckedResultKeys 不包含 key ,抛出一个
TypeError 异常。
从 uncheckedResultKeys 中移除 key 。
如果 extensibleTarget 是 true ,返回 trapResult 。
对 targetConfigurableKeys 的每个元素 key ,执行
如果 uncheckedResultKeys 不包含 key ,抛出一个
TypeError 异常。
从 uncheckedResultKeys 中移除 key 。
如果 uncheckedResultKeys 不是空的,抛出一个 TypeError 异常。
返回 trapResult 。
注
代理对象的 [[OwnPropertyKeys]] 强制执行以下不变量:
[[OwnPropertyKeys]] 的结果是一个 列表 。
返回的 列表 不包含重复条目。
返回的 列表 的每个元素都是一个
属性键 。
结果 列表
必须包含目标对象所有不可配置自有属性的键。
如果目标对象不可扩展,则结果 列表
必须包含目标对象自有属性的所有键,且不包含其他值。
10.5.12 [[Call]] ( thisArgument ,
argumentsList )
代理异质对象 O 的 [[Call]] 内部方法接受参数 thisArgument (一个 ECMAScript 语言值 )和
argumentsList (一个包含 ECMAScript 语言值 的 列表 )并返回 包含 ECMAScript 语言值 的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"apply" )。
如果 trap 是 undefined ,那么
返回 ? Call (target ,
thisArgument , argumentsList )。
让 argArray 为 CreateArrayFromList (argumentsList )。
返回 ? Call (trap , handler , «
target , thisArgument , argArray »)。
注
代理异质对象 只有在其 [[ProxyTarget]] 内部插槽的初始值是具有 [[Call]]
内部方法的对象时,才具有 [[Call]] 内部方法。
10.5.13 [[Construct]] (
argumentsList , newTarget )
代理异质对象 O 的 [[Construct]] 内部方法接受参数 argumentsList (一个包含 ECMAScript 语言值 的 列表 )和
newTarget (一个 构造函数 )并返回 包含 对象的正常完成或 抛出完成 。它在被调用时执行以下步骤:
执行 ? ValidateNonRevokedProxy (O )。
让 target 为 O .[[ProxyTarget]] 。
断言 :
IsConstructor (target ) 是
true 。
让 handler 为 O .[[ProxyHandler]] 。
断言 :
handler 是一个对象 。
让 trap 为 ? GetMethod (handler ,
"construct" )。
如果 trap 是 undefined ,那么
返回 ? Construct (target ,
argumentsList , newTarget )。
让 argArray 为 CreateArrayFromList (argumentsList )。
让 newObj 为 ? Call (trap , handler , «
target , argArray , newTarget »)。
如果 newObj 不是一个对象 ,抛出一个 TypeError
异常。
返回 newObj 。
注 1
代理异质对象 只有在其 [[ProxyTarget]] 内部插槽的初始值是具有 [[Construct]] 内部方法的对象时,才具有 [[Construct]] 内部方法。
注 2
代理对象的 [[Construct]] 强制执行以下不变量:
[[Construct]] 的结果必须是一个对象。
10.5.14 ValidateNonRevokedProxy ( proxy )
抽象操作 ValidateNonRevokedProxy 接受参数 proxy (一个 代理异质对象 )并返回 包含
unused 的正常完成或 抛出完成 。如果
proxy 已被撤销,它会抛出一个 TypeError 异常。它在被调用时执行以下步骤:
如果 proxy .[[ProxyTarget]] 是
null ,抛出一个 TypeError 异常。
断言 :
proxy .[[ProxyHandler]] 不是 null 。
返回 unused 。
10.5.15 ProxyCreate ( target , handler )
抽象操作 ProxyCreate 接受参数 target (一个 ECMAScript 语言值 )和
handler (一个 ECMAScript 语言值 )并返回 包含 代理异质对象 的正常完成或 抛出完成 。它用于指定新代理对象的创建。它在被调用时执行以下步骤:
如果 target 不是一个对象 ,抛出一个 TypeError
异常。
如果 handler 不是一个对象 ,抛出一个 TypeError
异常。
让 P 为 MakeBasicObject (« [[ProxyHandler]] , [[ProxyTarget]] »)。
将 P 的基本内部方法(除了 [[Call]] 和 [[Construct]] )设置为 10.5
中指定的定义。
如果 IsCallable (target ) 是
true ,那么
按照 10.5.12
中的指定设置 P .[[Call]] 。
如果 IsConstructor (target )
是 true ,那么
按照 10.5.13
中的指定设置 P .[[Construct]] 。
设置 P .[[ProxyTarget]] 为 target 。
设置 P .[[ProxyHandler]] 为 handler 。
返回 P 。
11 ECMAScript 语言:源文本
11.1 源文本
语法
SourceCharacter ::
任何 Unicode 码点
ECMAScript 源文本 是一个 Unicode 码点序列。所有从 U+0000 到 U+10FFFF 的 Unicode
码点值,包括代理码点,都可以出现在 ECMAScript 语法允许的 ECMAScript 源文本中。用于存储和交换 ECMAScript
源文本的实际编码与本规范无关。无论外部源文本编码如何,符合要求的 ECMAScript 实现都会将源文本处理为等效的 SourceCharacter 值序列,每个 SourceCharacter 都是一个 Unicode 码点。符合要求的 ECMAScript
实现不需要对源文本执行任何规范化,也不需要表现得好像它们正在执行源文本规范化。
组合字符序列的组成部分被视为单独的 Unicode 码点,即使用户可能认为整个序列是一个字符。
注
在字符串字面量、正则表达式字面量、模板字面量和标识符中,任何 Unicode 码点也可以使用明确表示码点数值的 Unicode
转义序列来表示。在注释中,这样的转义序列作为注释的一部分被有效忽略。
ECMAScript 在 Unicode 转义序列的行为上与 Java 编程语言不同。在 Java 程序中,如果 Unicode 转义序列 \u000A
出现在单行注释中,它会被解释为行终止符(Unicode 码点 U+000A 是换行符 (LF)),因此下一个码点不是注释的一部分。同样,如果 Unicode 转义序列
\u000A 出现在 Java 程序的字符串字面量中,它同样被解释为行终止符,这在字符串字面量中是不允许的——必须写 \n 而不是
\u000A 来使换行符 (LF) 成为字符串字面量值的一部分。在 ECMAScript 程序中,出现在注释中的 Unicode
转义序列永远不会被解释,因此不能促成注释的终止。同样,出现在 ECMAScript 程序字符串字面量中的 Unicode
转义序列总是对字面量有贡献,永远不会被解释为行终止符或可能终止字符串字面量的码点。
11.1.1 静态语义:UTF16EncodeCodePoint ( cp )
抽象操作 UTF16EncodeCodePoint 接受参数 cp (一个 Unicode 码点)并返回一个字符串。它在被调用时执行以下步骤:
断言 :0 ≤
cp ≤ 0x10FFFF。
如果 cp ≤ 0xFFFF,返回由数值为 cp 的码元组成的字符串值。
令 cu1 为数值为 floor ((cp - 0x10000) /
0x400) + 0xD800 的码元。
令 cu2 为数值为 ((cp - 0x10000)
modulo
0x400) + 0xDC00 的码元。
返回 cu1 和 cu2 的 字符串连接 。
11.1.2 静态语义:CodePointsToString ( text )
抽象操作 CodePointsToString 接受参数 text (一个 Unicode 码点序列)并返回一个字符串。它将 text
转换为字符串值,如 6.1.4 中所述。它在被调用时执行以下步骤:
令 result 为空字符串。
对于 text 的每个码点 cp ,执行
设置 result 为 result 和 UTF16EncodeCodePoint (cp )
的 字符串连接 。
返回 result 。
11.1.3 静态语义:UTF16SurrogatePairToCodePoint (
lead , trail )
抽象操作 UTF16SurrogatePairToCodePoint 接受参数 lead (一个码元)和 trail (一个码元)并返回一个码点。形成
UTF-16 代理对 的两个码元被转换为码点。它在被调用时执行以下步骤:
断言 :
lead 是一个 前导代理 ,trail
是一个 后尾代理 。
令 cp 为 (lead - 0xD800) × 0x400 + (trail - 0xDC00) +
0x10000。
返回码点 cp 。
11.1.4 静态语义:CodePointAt ( string ,
position )
抽象操作 CodePointAt 接受参数 string (一个字符串)和 position (一个非负 整数 )并返回一个具有字段 [[CodePoint]] (一个码点)、[[CodeUnitCount]]
(一个正 整数 )和 [[IsUnpairedSurrogate]] (一个布尔值)的 记录 。它将 string
解释为 UTF-16 编码的码点序列,如 6.1.4
中所述,并从中读取一个从索引 position 处的码元开始的单个码点。它在被调用时执行以下步骤:
令 size 为 string 的长度。
断言 :
position ≥ 0 且 position < size 。
令 first 为 string 中索引 position 处的码元。
令 cp 为数值等于 first 数值的码点。
如果 first 既不是 前导代理 也不是 后尾代理 ,那么
返回 记录 {
[[CodePoint]] : cp , [[CodeUnitCount]] : 1, [[IsUnpairedSurrogate]] :
false }。
如果 first 是 后尾代理 或 position + 1 =
size ,那么
返回 记录 {
[[CodePoint]] : cp , [[CodeUnitCount]] : 1, [[IsUnpairedSurrogate]] : true }。
令 second 为 string 中索引 position + 1 处的码元。
如果 second 不是 后尾代理 ,那么
返回 记录 {
[[CodePoint]] : cp , [[CodeUnitCount]] : 1, [[IsUnpairedSurrogate]] : true }。
设置 cp 为 UTF16SurrogatePairToCodePoint (first ,
second )。
返回 记录 { [[CodePoint]] : cp , [[CodeUnitCount]] : 2, [[IsUnpairedSurrogate]] : false }。
11.1.5 静态语义:StringToCodePoints ( string )
抽象操作 StringToCodePoints 接受参数 string (一个字符串)并返回一个码点的 列表 。它返回将 string
解释为 UTF-16 编码的 Unicode 文本所产生的 Unicode 码点序列,如 6.1.4 中所述。它在被调用时执行以下步骤:
令 codePoints 为一个新的空 列表 。
令 size 为 string 的长度。
令 position 为 0。
重复,当 position < size 时,
令 cp 为 CodePointAt (string ,
position )。
将 cp .[[CodePoint]] 追加到
codePoints 。
设置 position 为 position + cp .[[CodeUnitCount]] 。
返回 codePoints 。
11.1.6 静态语义:ParseText ( sourceText ,
goalSymbol )
抽象操作 ParseText 接受参数 sourceText (一个字符串或 Unicode 码点序列)和 goalSymbol (ECMAScript
语法中的一个非终结符)并返回一个 解析节点 或一个非空的 SyntaxError
对象 列表 。它在被调用时执行以下步骤:
如果 sourceText 是一个字符串 ,设置
sourceText 为 StringToCodePoints (sourceText )。
尝试使用 goalSymbol 作为 目标符号 来解析
sourceText ,并分析解析结果以查找任何 早期错误 条件。解析和 早期错误 检测可以以 实现定义 的方式交错进行。
如果解析成功且未发现 早期错误 ,返回解析产生的解析树根部的 解析节点 (goalSymbol 的一个实例)。
否则,返回一个包含一个或多个表示解析错误和/或 早期错误 的 SyntaxError 对象的
列表 。如果存在多个解析错误或
早期错误 ,列表中错误对象的数量和顺序是 实现定义 的,但至少必须存在一个。
注 1
考虑一个在特定点有 早期错误 ,在后面的点也有语法错误的文本。一个先执行解析阶段再执行 早期错误
阶段的实现可能会报告语法错误而不继续进行 早期错误 阶段。一个交错进行这两个活动的实现可能会报告 早期错误
而不继续查找语法错误。第三种实现可能会报告两个错误。所有这些行为都是符合要求的。
注 2
11.2 源代码类型
ECMAScript 代码有四种类型:
注 1
函数代码通常作为函数定义(15.2 )、箭头函数定义
(15.3 )、方法定义
(15.4 )、生成器函数定义
(15.5 )、异步函数定义
(15.8 )、异步生成器函数定义
(15.6 )
和异步箭头函数(15.9 )的主体提供。
函数代码也派生自 Function 构造函数
(20.2.1.1 )、GeneratorFunction
构造函数 (27.3.1.1 )和 AsyncFunction
构造函数 (27.7.1.1 )的参数。
注 2
将 BindingIdentifier
包含在函数代码中的实际效果是,严格模式代码 的早期错误会应用于作为函数名称的 BindingIdentifier ,该函数的主体包含 "use strict"
指令,即使周围的代码不是 严格模式代码 。
11.2.1 指令序言和 Use Strict 指令
指令序言 是作为 FunctionBody 、ScriptBody 或 ModuleBody 的初始 StatementListItem 或 ModuleItem 出现的最长 ExpressionStatement
序列,并且序列中的每个 ExpressionStatement 完全由一个 StringLiteral
标记后跟一个分号组成。分号可以显式出现,也可以通过自动分号插入(12.10 )插入。一个
指令序言 可以是一个空序列。
Use Strict 指令
是 指令序言 中的一个 ExpressionStatement ,其 StringLiteral 是精确的码点序列
"use strict" 或 'use strict'。一个 Use Strict 指令 不能包含 EscapeSequence 或 LineContinuation 。
一个 指令序言 可能包含多个 Use Strict
指令 。但是,如果发生这种情况,实现可能会发出警告。
注
指令序言 的 ExpressionStatement
在包含的产生式求值期间正常求值。实现可以为那些不是 Use Strict 指令 且出现在 指令序言 中的 ExpressionStatement
定义实现特定的含义。如果存在适当的通知机制,当实现在 指令序言 中遇到一个不是 Use
Strict 指令 且没有由实现定义的含义的 ExpressionStatement 时,应发出警告。
11.2.2 严格模式代码
ECMAScript 句法单元可以使用非限制性或严格模式语法和语义(4.3.2 )进行处理。在以下情况下,代码被解释为 严格模式代码 :
不是严格模式代码的 ECMAScript 代码称为 非严格代码 。
11.2.2.1 静态语义:IsStrict ( node )
抽象操作 IsStrict 接受参数 node (一个 解析节点 )并返回一个布尔值。它在被调用时执行以下步骤:
如果 node 匹配的源文本 是
严格模式代码 ,返回
true ;否则返回 false 。
11.2.3 非 ECMAScript 函数
ECMAScript 实现可以支持对函数 奇异对象 的求值,其求值行为以某种 宿主定义 的可执行代码形式表示,而不是 ECMAScript
源文本 。从调用或被此类 函数对象 调用的 ECMAScript 代码的角度来看,函数对象 是在
ECMAScript 代码中定义的还是内置函数是不可观察的。
12 ECMAScript 语言:词法语法
ECMAScript 脚本 或 模块
的源文本首先被转换为输入元素序列,这些输入元素是标记、行终止符、注释或空白符。源文本从左到右扫描,重复地取尽可能长的码点序列作为下一个输入元素。
在某些情况下,词法输入元素的识别对消费输入元素的句法语法上下文很敏感。这需要词法语法具有多个 目标符号 。InputElementHashbangOrRegExp 目标用于 脚本 或 模块 的开始。InputElementRegExpOrTemplateTail
目标用于允许 RegularExpressionLiteral 、TemplateMiddle 或 TemplateTail 的句法语法上下文中。InputElementRegExp 目标符号 用于所有允许 RegularExpressionLiteral 但不允许 TemplateMiddle 或 TemplateTail 的句法语法上下文中。InputElementTemplateTail
目标用于所有允许 TemplateMiddle 或 TemplateTail 但不允许 RegularExpressionLiteral
的句法语法上下文中。在所有其他上下文中,InputElementDiv
用作词法 目标符号 。
注
使用多个词法目标确保不存在会影响自动分号插入的词法歧义。例如,不存在既允许前导除法或除法赋值又允许前导 RegularExpressionLiteral
的句法语法上下文。这不受分号插入的影响(参见 12.10 );在如下例子中:
a = b
/hi/g.exec (c).map (d);
其中 LineTerminator
后第一个非空白、非注释码点是 U+002F(斜线),且句法上下文允许除法或除法赋值,则不会在 LineTerminator 处插入分号。也就是说,上述例子的解释方式与以下相同:
a = b / hi / g.exec (c).map (d);
语法
InputElementDiv ::
WhiteSpace
LineTerminator
Comment
CommonToken
DivPunctuator
RightBracePunctuator
InputElementRegExp ::
WhiteSpace
LineTerminator
Comment
CommonToken
RightBracePunctuator
RegularExpressionLiteral
InputElementRegExpOrTemplateTail
::
WhiteSpace
LineTerminator
Comment
CommonToken
RegularExpressionLiteral
TemplateSubstitutionTail
InputElementTemplateTail
::
WhiteSpace
LineTerminator
Comment
CommonToken
DivPunctuator
TemplateSubstitutionTail
InputElementHashbangOrRegExp
::
WhiteSpace
LineTerminator
Comment
CommonToken
HashbangComment
RegularExpressionLiteral
12.1 Unicode 格式控制字符
Unicode 格式控制字符(即 Unicode 字符数据库中类别为 "Cf" 的字符,如从左到右标记或从右到左标记)是在缺乏用于此目的的高级协议(如标记语言)的情况下用于控制文本范围格式的控制代码。
允许格式控制字符出现在源文本中是有用的,以便于编辑和显示。所有格式控制字符都可以在注释中以及字符串字面量、模板字面量和正则表达式字面量中使用。
U+FEFF(零宽度无间断空格)是一个格式控制字符,主要用于文本的开头,以将其标记为 Unicode 并允许检测文本的编码和字节顺序。用于此目的的 <ZWNBSP>
字符有时也可能出现在文本开头之后,例如作为连接文件的结果。在 ECMAScript 源文本 中,<ZWNBSP>
码点在注释、字符串字面量、模板字面量和正则表达式字面量之外被视为空白字符(参见 12.2 )。
12.2 空白符
空白码点用于改善源文本的可读性并将标记(不可分割的词法单元)彼此分离,但在其他方面是无关紧要的。空白码点可以出现在任意两个标记之间以及输入的开始或结束处。空白码点可以出现在 StringLiteral 、RegularExpressionLiteral 、Template 或 TemplateSubstitutionTail
中,在这些地方它们被视为构成字面量值一部分的重要码点。它们也可以出现在 Comment 中,但不能出现在任何其他类型的标记内。
ECMAScript 空白码点列在 表 35 中。
表 35:空白码点
码点
名称
缩写
U+0009
字符制表符
<TAB>
U+000B
行制表符
<VT>
U+000C
换页符 (FF)
<FF>
U+FEFF
零宽度无间断空格
<ZWNBSP>
通用类别 "Space_Separator" 中的任何码点
<USP>
注 1
U+0020(空格)和 U+00A0(无间断空格)码点是 <USP> 的一部分。
注 2
除了 表 35 中列出的码点外,ECMAScript WhiteSpace 有意排除了所有具有 Unicode
"White_Space" 属性但未归类为通用类别 "Space_Separator"("Zs")的码点。
语法
WhiteSpace ::
<TAB>
<VT>
<FF>
<ZWNBSP>
<USP>
12.3 行终止符
与空白码点一样,行终止符码点用于改善源文本的可读性并将标记(不可分割的词法单元)彼此分离。但是,与空白码点不同,行终止符对句法语法的行为有一定影响。通常,行终止符可以出现在任意两个标记之间,但在句法语法禁止的少数地方则不行。行终止符还会影响自动分号插入的过程(12.10 )。行终止符不能出现在任何标记内,除了 StringLiteral 、Template 或 TemplateSubstitutionTail 。<LF> 和
<CR> 行终止符不能出现在 StringLiteral 标记内,除非作为 LineContinuation 的一部分。
行终止符可以出现在 MultiLineComment
内,但不能出现在 SingleLineComment 内。
行终止符被包含在正则表达式中 \s 类匹配的空白码点集合中。
ECMAScript 行终止符码点列在 表 36 中。
表 36:行终止符码点
码点
Unicode 名称
缩写
U+000A
换行符 (LF)
<LF>
U+000D
回车符 (CR)
<CR>
U+2028
行分隔符
<LS>
U+2029
段分隔符
<PS>
只有 表 36 中的 Unicode 码点被视为行终止符。其他换行或断行的
Unicode 码点不被视为行终止符,但如果它们满足 表 35 中列出的要求,则被视为空白符。序列
<CR><LF> 通常用作行终止符。为了报告行号的目的,它应该被视为单个 SourceCharacter 。
语法
LineTerminator ::
<LF>
<CR>
<LS>
<PS>
LineTerminatorSequence
::
<LF>
<CR>
[lookahead ≠ <LF> ]
<LS>
<PS>
<CR>
<LF>
12.5 Hashbang 注释
Hashbang 注释对位置敏感,与其他类型的注释一样,从句法语法的输入元素流中被丢弃。
语法
12.6 标记
语法
CommonToken ::
IdentifierName
PrivateIdentifier
Punctuator
NumericLiteral
StringLiteral
Template
注
12.7 名称和关键字
IdentifierName 和 ReservedWord 是根据 Unicode 标准附件
#31《标识符和模式语法》中给定的默认标识符语法进行解释的标记,但有一些小的修改。ReservedWord 是 IdentifierName 的一个枚举子集。句法语法将 Identifier 定义为不是 ReservedWord 的 IdentifierName 。Unicode 标识符语法基于
Unicode 标准规定的字符属性。所有符合的 ECMAScript 实现必须将最新版本 Unicode 标准中指定类别的 Unicode 码点视为属于那些类别。ECMAScript 实现可以识别在
Unicode 标准后续版本中定义的标识符码点。
注 1
本标准规定了特定的码点添加:U+0024(美元符号)和 U+005F(下划线)允许出现在 IdentifierName 的任何位置。
语法
PrivateIdentifier ::
#
IdentifierName
IdentifierName ::
IdentifierStart
IdentifierName
IdentifierPart
IdentifierStart ::
IdentifierStartChar
\
UnicodeEscapeSequence
IdentifierPart ::
IdentifierPartChar
\
UnicodeEscapeSequence
IdentifierStartChar
::
UnicodeIDStart
$
_
IdentifierPartChar ::
UnicodeIDContinue
$
AsciiLetter ::
one of a b c
d e f g h
i j k l m
n o p q r
s t u v w
x y z A B
C D E F G
H I J K L
M N O P Q
R S T U V
W X Y Z
UnicodeIDStart ::
任何具有 Unicode 属性 "ID_Start" 的 Unicode 码点
UnicodeIDContinue ::
任何具有 Unicode 属性 "ID_Continue" 的 Unicode 码点
非终结符 UnicodeEscapeSequence
的定义在 12.9.4 中给出。
注 2
注 3
具有 Unicode 属性 "ID_Start" 和 "ID_Continue" 的码点集合分别包括具有 Unicode 属性 "Other_ID_Start" 和
"Other_ID_Continue" 的码点。
12.7.1 标识符名称
Unicode 转义序列在 IdentifierName
中是允许的,它们贡献一个等于 UnicodeEscapeSequence 的 IdentifierCodePoint 的单个 Unicode
码点。UnicodeEscapeSequence 前面的 \
不贡献任何码点。UnicodeEscapeSequence 不能用于为 IdentifierName
贡献一个本来无效的码点。换句话说,如果 \ UnicodeEscapeSequence 序列被它所贡献的 SourceCharacter 替换,结果仍然必须是一个有效的
IdentifierName ,且具有与原始
IdentifierName 完全相同的 SourceCharacter 元素序列。本规范中对
IdentifierName
的所有解释都基于它们的实际码点,无论是否使用转义序列来贡献任何特定码点。
根据 Unicode 标准规范等价的两个 IdentifierName 是不 相等的,除非在替换每个 UnicodeEscapeSequence
后,它们由完全相同的码点序列表示。
12.7.1.1 静态语义:早期错误
IdentifierStart
::
\
UnicodeEscapeSequence
IdentifierPart ::
\
UnicodeEscapeSequence
12.7.1.2 静态语义:IdentifierCodePoints
语法导向操作
IdentifierCodePoints 不接受参数并返回码点的 列表 。它在以下产生式上分段定义:
IdentifierName ::
IdentifierStart
设 cp 为 IdentifierStart 的 IdentifierCodePoint 。
返回 « cp »。
IdentifierName ::
IdentifierName
IdentifierPart
设 cps 为派生的 IdentifierName 的 IdentifierCodePoints 。
设 cp 为 IdentifierPart 的 IdentifierCodePoint 。
返回 cps 和 « cp » 的 列表连接 。
12.7.1.3 静态语义:IdentifierCodePoint
语法导向操作
IdentifierCodePoint 不接受参数并返回一个码点。它在以下产生式上分段定义:
IdentifierStart
:: IdentifierStartChar
返回 IdentifierStartChar 匹配的码点。
IdentifierPart ::
IdentifierPartChar
返回 IdentifierPartChar 匹配的码点。
UnicodeEscapeSequence
::
u
Hex4Digits
返回数值等于 Hex4Digits 的
MV 的码点。
UnicodeEscapeSequence
::
u{
CodePoint
}
返回数值等于 CodePoint 的 MV
的码点。
12.7.2 关键字和保留字
关键字 是匹配 IdentifierName
但也有句法用途的标记;也就是说,它在某些句法产生式中以固定宽度字体直接出现。ECMAScript 的关键字包括
if、while、async、await 等等。
保留字 是不能用作标识符的 IdentifierName 。许多关键字是保留字,但有些不是,有些只在特定上下文中保留。if
和 while 是保留字。await 只在异步函数和模块内保留。async
不是保留的;它可以无限制地用作变量名或语句标签。
本规范使用语法产生式和 早期错误 规则的组合来指定哪些名称是有效标识符,哪些是保留字。下面 ReservedWord 列表中的所有标记,除了
await 和 yield,都是无条件保留的。await 和 yield 的例外在
13.1
中使用参数化句法产生式指定。最后,几个 早期错误 规则限制有效标识符的集合。参见 13.1.1 、14.3.1.1 、14.7.5.1
和 15.7.1 。总结来说,标识符名称有五个类别:
总是允许作为标识符且不是关键字的,如 Math、window、toString 和
_;
从不允许作为标识符的,即下面列出的 ReservedWord (除了 await 和
yield);
上下文允许作为标识符的,即 await 和 yield;
在 严格模式代码
中上下文不允许作为标识符的:let、static、implements、interface、package、private、protected
和 public;
总是允许作为标识符,但也在某些句法产生式中作为关键字出现,在不允许 Identifier
的地方:as、async、from、get、meta、of、set
和 target。
条件关键字 或 上下文关键字 这个术语有时用来指属于后三个类别的关键字,因此可以在某些上下文中用作标识符,在其他上下文中用作关键字。
语法
ReservedWord ::
one of await break
case catch class const
continue debugger default
delete do else enum
export extends false finally
for function if import
in instanceof new null
return super switch this
throw true try typeof
var void while with
yield
注 1
根据 5.1.5 ,语法中的关键字匹配特定 SourceCharacter
元素的文字序列。关键字中的码点不能用 \ UnicodeEscapeSequence 表示。
IdentifierName 可以包含
\ UnicodeEscapeSequence ,但不可能通过拼写
els\u{65} 来声明名为 "else" 的变量。13.1.1 中的
早期错误
规则排除了与保留字具有相同 StringValue 的标识符。
注 2
enum 目前在本规范中未用作关键字。它是一个未来保留字 ,留作未来语言扩展中用作关键字。
类似地,implements、interface、package、private、protected
和 public 在 严格模式代码 中是未来保留字。
注 3
名称 arguments 和 eval 不是关键字,但它们在 严格模式代码 中受到一些限制。参见 13.1.1 、8.6.4 、15.2.1 、15.5.1 、15.6.1
和 15.8.1 。
12.8 标点符号
语法
Punctuator ::
OptionalChainingPunctuator
OtherPunctuator
OptionalChainingPunctuator
::
?.
[lookahead ∉ DecimalDigit ]
OtherPunctuator ::
one of { ( )
[ ] . ... ;
, < > <=
>= == != ===
!== + - * %
** ++ -- <<
>> >>> & |
^ ! ~ &&
|| ?? ? : =
+= -= *= %= **=
<<= >>= >>>=
&= |= ^= &&=
||= ??= =>
DivPunctuator ::
/
/=
RightBracePunctuator
::
}
12.9 字面量
12.9.1 Null 字面量
语法
NullLiteral ::
null
12.9.2 布尔字面量
语法
BooleanLiteral ::
true
false
12.9.3 数值字面量
语法
NumericLiteralSeparator
::
_
NumericLiteral ::
DecimalLiteral
DecimalBigIntegerLiteral
NonDecimalIntegerLiteral [+Sep]
NonDecimalIntegerLiteral [+Sep]
BigIntLiteralSuffix
LegacyOctalIntegerLiteral
DecimalBigIntegerLiteral
::
0
BigIntLiteralSuffix
NonZeroDigit
DecimalDigits [+Sep] opt
BigIntLiteralSuffix
NonZeroDigit
NumericLiteralSeparator
DecimalDigits [+Sep]
BigIntLiteralSuffix
NonDecimalIntegerLiteral [Sep]
::
BinaryIntegerLiteral [?Sep]
OctalIntegerLiteral [?Sep]
HexIntegerLiteral [?Sep]
BigIntLiteralSuffix
::
n
DecimalLiteral ::
DecimalIntegerLiteral
.
DecimalDigits [+Sep] opt
ExponentPart [+Sep] opt
.
DecimalDigits [+Sep]
ExponentPart [+Sep] opt
DecimalIntegerLiteral
ExponentPart [+Sep] opt
DecimalIntegerLiteral
::
0
NonZeroDigit
NonZeroDigit
NumericLiteralSeparator opt
DecimalDigits [+Sep]
NonOctalDecimalIntegerLiteral
DecimalDigits [Sep]
::
DecimalDigit
DecimalDigits [?Sep]
DecimalDigit
[+Sep]
DecimalDigits [+Sep]
NumericLiteralSeparator
DecimalDigit
DecimalDigit ::
one of 0 1 2
3 4 5 6 7
8 9
NonZeroDigit ::
one of 1 2 3
4 5 6 7 8
9
ExponentPart [Sep]
::
ExponentIndicator
SignedInteger [?Sep]
ExponentIndicator
:: one of e
E
SignedInteger [Sep]
::
DecimalDigits [?Sep]
+
DecimalDigits [?Sep]
-
DecimalDigits [?Sep]
BinaryIntegerLiteral [Sep]
::
0b
BinaryDigits [?Sep]
0B
BinaryDigits [?Sep]
BinaryDigits [Sep]
::
BinaryDigit
BinaryDigits [?Sep]
BinaryDigit
[+Sep]
BinaryDigits [+Sep]
NumericLiteralSeparator
BinaryDigit
BinaryDigit ::
one of 0 1
OctalIntegerLiteral [Sep]
::
0o
OctalDigits [?Sep]
0O
OctalDigits [?Sep]
OctalDigits [Sep]
::
OctalDigit
OctalDigits [?Sep]
OctalDigit
[+Sep]
OctalDigits [+Sep]
NumericLiteralSeparator
OctalDigit
LegacyOctalIntegerLiteral
::
0
OctalDigit
LegacyOctalIntegerLiteral
OctalDigit
NonOctalDecimalIntegerLiteral
::
0
NonOctalDigit
LegacyOctalLikeDecimalIntegerLiteral
NonOctalDigit
NonOctalDecimalIntegerLiteral
DecimalDigit
LegacyOctalLikeDecimalIntegerLiteral
::
0
OctalDigit
LegacyOctalLikeDecimalIntegerLiteral
OctalDigit
OctalDigit ::
one of 0 1 2
3 4 5 6
7
NonOctalDigit ::
one of 8 9
HexIntegerLiteral [Sep]
::
0x
HexDigits [?Sep]
0X
HexDigits [?Sep]
HexDigits [Sep]
::
HexDigit
HexDigits [?Sep]
HexDigit
[+Sep]
HexDigits [+Sep]
NumericLiteralSeparator
HexDigit
HexDigit :: one
of 0 1 2
3 4 5 6 7
8 9 a b c
d e f A B
C D E F
紧跟在 NumericLiteral 后面的
SourceCharacter 不能是 IdentifierStart 或 DecimalDigit 。
注
例如:3in 是一个错误,而不是两个输入元素 3 和 in。
12.9.3.1 静态语义:早期错误
NumericLiteral ::
LegacyOctalIntegerLiteral
DecimalIntegerLiteral
:: NonOctalDecimalIntegerLiteral
如果 IsStrict (this production) 是
true ,则这是语法错误。
注
12.9.3.2 静态语义:MV
数值字面量表示 Number 类型 或
BigInt 类型 的值。
12.9.3.3 静态语义:NumericValue
语法导向操作
NumericValue 不接受参数并返回一个 Number 或 BigInt。它在以下产生式上分段定义:
NumericLiteral ::
DecimalLiteral
返回 RoundMVResult (DecimalLiteral 的
MV)。
NumericLiteral ::
NonDecimalIntegerLiteral
返回 𝔽 (NonDecimalIntegerLiteral
的 MV)。
NumericLiteral ::
LegacyOctalIntegerLiteral
返回 𝔽 (LegacyOctalIntegerLiteral
的 MV)。
NumericLiteral ::
NonDecimalIntegerLiteral
BigIntLiteralSuffix
返回 NonDecimalIntegerLiteral
的 MV 的 BigInt 值 。
DecimalBigIntegerLiteral
::
0
BigIntLiteralSuffix
返回 0 ℤ 。
DecimalBigIntegerLiteral
::
NonZeroDigit
BigIntLiteralSuffix
返回 NonZeroDigit 的
MV 的 BigInt 值 。
DecimalBigIntegerLiteral
::
NonZeroDigit
DecimalDigits
BigIntLiteralSuffix
NonZeroDigit
NumericLiteralSeparator
DecimalDigits
BigIntLiteralSuffix
让 n 为 DecimalDigits 中的码点数,不包括所有 NumericLiteralSeparator
的出现。
让 mv 为(NonZeroDigit 的 MV ×
10n )加上 DecimalDigits 的 MV。
返回 ℤ (mv )。
12.9.4 字符串字面量
注 1
字符串字面量是用单引号或双引号括起来的 0 个或多个 Unicode 码点。Unicode
码点也可以用转义序列表示。除了结束引号码点、U+005C(反斜杠)、U+000D(回车符)和
U+000A(换行符)之外,所有码点都可以直接出现在字符串字面量中。任何码点都可以以转义序列的形式出现。字符串字面量求值为 ECMAScript String 值。生成这些
String 值时,Unicode 码点按照 11.1.1 中定义的方式进行 UTF-16
编码。属于基本多语言平面的码点被编码为字符串的单个码元素。所有其他码点被编码为字符串的两个码元素。
语法
StringLiteral ::
"
DoubleStringCharacters opt
"
'
SingleStringCharacters opt
'
DoubleStringCharacters
::
DoubleStringCharacter
DoubleStringCharacters opt
SingleStringCharacters
::
SingleStringCharacter
SingleStringCharacters opt
DoubleStringCharacter
::
SourceCharacter
but not one of " or \ or LineTerminator
<LS>
<PS>
\
EscapeSequence
LineContinuation
SingleStringCharacter
::
SourceCharacter
but not one of ' or \ or LineTerminator
<LS>
<PS>
\
EscapeSequence
LineContinuation
LineContinuation ::
\
LineTerminatorSequence
EscapeSequence ::
CharacterEscapeSequence
0
[lookahead ∉ DecimalDigit ]
LegacyOctalEscapeSequence
NonOctalDecimalEscapeSequence
HexEscapeSequence
UnicodeEscapeSequence
CharacterEscapeSequence
::
SingleEscapeCharacter
NonEscapeCharacter
SingleEscapeCharacter
:: one of '
" \ b f n
r t v
NonEscapeCharacter
::
SourceCharacter
but not one of EscapeCharacter or LineTerminator
EscapeCharacter ::
SingleEscapeCharacter
DecimalDigit
x
u
LegacyOctalEscapeSequence
::
0
[lookahead ∈ { 8 , 9 }]
NonZeroOctalDigit
[lookahead ∉ OctalDigit ]
ZeroToThree
OctalDigit
[lookahead ∉ OctalDigit ]
FourToSeven
OctalDigit
ZeroToThree
OctalDigit
OctalDigit
NonZeroOctalDigit
::
OctalDigit but
not 0
ZeroToThree ::
one of 0 1 2
3
FourToSeven ::
one of 4 5 6
7
NonOctalDecimalEscapeSequence
:: one of 8
9
HexEscapeSequence
::
x
HexDigit
HexDigit
UnicodeEscapeSequence
::
u
Hex4Digits
u{
CodePoint
}
Hex4Digits ::
HexDigit
HexDigit
HexDigit
HexDigit
非终结符 HexDigit 的定义在 12.9.3 中给出。SourceCharacter 在 11.1 中定义。
注 2
<LF> 和 <CR> 不能出现在字符串字面量中,除非作为 LineContinuation
的一部分来产生空码点序列。在字符串字面量的 String 值中包含它们的正确方法是使用转义序列,如 \n 或 \u000A。
12.9.4.1 静态语义:早期错误
EscapeSequence ::
LegacyOctalEscapeSequence
NonOctalDecimalEscapeSequence
如果 IsStrict (this production) 是
true ,则这是语法错误。
注 1
注 2
字符串字面量可能出现在将封闭代码置于 严格模式 的 Use
Strict 指令 之前,实现必须注意对这类字面量强制执行上述规则。例如,以下源文本包含语法错误:
function invalid ( ) { "\7" ; "use strict" ; }
12.9.4.2 静态语义:SV
语法导向操作
SV 不接受参数并返回一个 String。
字符串字面量表示 String 类型 的值。SV
通过对字符串字面量的各个部分进行递归应用来为字符串字面量产生 String 值。作为此过程的一部分,字符串字面量内的一些 Unicode 码点被解释为具有 数学值 ,如下所述或在 12.9.3 中所述。
表 37:字符串单字符转义序列
转义序列
码元值
Unicode 字符名称
符号
\b
0x0008
BACKSPACE
<BS>
\t
0x0009
CHARACTER TABULATION
<HT>
\n
0x000A
LINE FEED (LF)
<LF>
\v
0x000B
LINE TABULATION
<VT>
\f
0x000C
FORM FEED (FF)
<FF>
\r
0x000D
CARRIAGE RETURN (CR)
<CR>
\"
0x0022
QUOTATION MARK
"
\'
0x0027
APOSTROPHE
'
\\
0x005C
REVERSE SOLIDUS
\
12.9.4.3 静态语义:MV
12.9.5 正则表达式字面量
注 1
正则表达式字面量是一个输入元素,每次求值该字面量时都会被转换为 RegExp 对象(参见 22.2 )。程序中的两个正则表达式字面量求值为正则表达式对象,即使两个字面量的内容相同,它们也永远不会比较为
===。RegExp 对象也可以在运行时通过 new RegExp 或调用 RegExp 构造函数
作为函数来创建(参见 22.2.4 )。
下面的产生式描述了正则表达式字面量的语法,并被输入元素扫描器用来找到正则表达式字面量的结尾。包含 RegularExpressionBody 和 RegularExpressionFlags
的源文本随后使用更严格的 ECMAScript 正则表达式语法(22.2.1 )再次解析。
实现可以扩展在 22.2.1 中定义的 ECMAScript 正则表达式语法,但不得扩展下面定义的 RegularExpressionBody 和
RegularExpressionFlags 产生式或这些产生式使用的产生式。
语法
RegularExpressionLiteral
::
/
RegularExpressionBody
/
RegularExpressionFlags
RegularExpressionBody
::
RegularExpressionFirstChar
RegularExpressionChars
RegularExpressionChars
::
[empty]
RegularExpressionChars
RegularExpressionChar
RegularExpressionFirstChar
::
RegularExpressionNonTerminator
but not one of * or \ or / or
[
RegularExpressionBackslashSequence
RegularExpressionClass
RegularExpressionChar
::
RegularExpressionNonTerminator
but not one of \ or / or
[
RegularExpressionBackslashSequence
RegularExpressionClass
RegularExpressionBackslashSequence
::
\
RegularExpressionNonTerminator
RegularExpressionNonTerminator
::
SourceCharacter
but not LineTerminator
RegularExpressionClass
::
[
RegularExpressionClassChars
]
RegularExpressionClassChars
::
[empty]
RegularExpressionClassChars
RegularExpressionClassChar
RegularExpressionClassChar
::
RegularExpressionNonTerminator
but not one of ] or \
RegularExpressionBackslashSequence
RegularExpressionFlags
::
[empty]
RegularExpressionFlags
IdentifierPartChar
注 2
正则表达式字面量不能为空;码元序列 //
不是表示空正则表达式字面量,而是开始单行注释。要指定空正则表达式,请使用:/(?:)/。
12.9.5.1 静态语义:BodyText
语法导向操作
BodyText 不接受参数并返回源文本。它在以下产生式上分段定义:
RegularExpressionLiteral
::
/
RegularExpressionBody
/
RegularExpressionFlags
返回被识别为 RegularExpressionBody 的源文本。
12.9.5.2 静态语义:FlagText
语法导向操作
FlagText 不接受参数并返回源文本。它在以下产生式上分段定义:
RegularExpressionLiteral
::
/
RegularExpressionBody
/
RegularExpressionFlags
返回被识别为 RegularExpressionFlags
的源文本。
12.9.6 模板字面量词法组件
语法
Template ::
NoSubstitutionTemplate
TemplateHead
NoSubstitutionTemplate
::
`
TemplateCharacters opt
`
TemplateHead ::
`
TemplateCharacters opt
${
TemplateSubstitutionTail
::
TemplateMiddle
TemplateTail
TemplateMiddle ::
}
TemplateCharacters opt
${
TemplateTail ::
}
TemplateCharacters opt
`
TemplateCharacters
::
TemplateCharacter
TemplateCharacters opt
TemplateCharacter
::
$
[lookahead ≠ { ]
\
TemplateEscapeSequence
\
NotEscapeSequence
LineContinuation
LineTerminatorSequence
SourceCharacter
but not one of ` or \ or $ or
LineTerminator
TemplateEscapeSequence
::
CharacterEscapeSequence
0
[lookahead ∉ DecimalDigit ]
HexEscapeSequence
UnicodeEscapeSequence
NotEscapeSequence
::
0
DecimalDigit
DecimalDigit
but not 0
x
[lookahead ∉ HexDigit ]
x
HexDigit
[lookahead ∉ HexDigit ]
u
[lookahead ∉ HexDigit ]
[lookahead ≠ { ]
u
HexDigit
[lookahead ∉ HexDigit ]
u
HexDigit
HexDigit
[lookahead ∉ HexDigit ]
u
HexDigit
HexDigit
HexDigit
[lookahead ∉ HexDigit ]
u
{
[lookahead ∉ HexDigit ]
u
{
NotCodePoint
[lookahead ∉ HexDigit ]
u
{
CodePoint
[lookahead ∉ HexDigit ]
[lookahead ≠ } ]
NotCodePoint ::
HexDigits [~Sep]
but only if the MV of HexDigits > 0x10FFFF
CodePoint ::
HexDigits [~Sep]
but only if the MV of HexDigits ≤ 0x10FFFF
注
12.9.6.1 静态语义:TV
语法导向操作
TV 不接受参数并返回 String 或 undefined 。模板字面量组件被 TV 解释为 String 类型 的值。TV
用于构造模板对象的索引组件(通俗地说,模板值)。在 TV 中,转义序列被转义序列表示的 Unicode 码点的 UTF-16 码元替换。
12.9.6.2 静态语义:TRV
语法导向操作
TRV 不接受参数并返回 String。模板字面量组件被 TRV 解释为 String 类型 的值。TRV
用于构造模板对象的原始组件(通俗地说,模板原始值)。TRV 类似于 TV ,区别在于在 TRV 中,转义序列按照它们在字面量中出现的方式被解释。
注
TV 排除 LineContinuation
的码元,而 TRV 包含它们。<CR><LF> 和 <CR> LineTerminatorSequence 对于
TV 和 TRV 都被规范化为
<LF>。需要显式的 TemplateEscapeSequence 来包含
<CR> 或 <CR><LF> 序列。
12.10 自动分号插入
大多数 ECMAScript
语句和声明必须以分号结尾。这些分号可以始终显式地出现在源文本中。但是,为了方便起见,在某些情况下可以从源文本中省略这些分号。这些情况通过说分号在这些情况下被自动插入到源代码标记流中来描述。
12.10.1 自动分号插入规则
在以下规则中,"标记"是指使用当前词法目标符号 确定的实际识别的词法标记,如第 12 章所述。
分号插入有三个基本规则:
当从左到右解析源文本时,遇到语法的任何产生式都不允许的标记(称为违规标记 ),如果满足以下一个或多个条件,则在违规标记之前自动插入分号:
当从左到右解析源文本时,遇到标记输入流的结尾,并且解析器无法将输入标记流解析为目标非终结符的单个实例,则在输入流的结尾自动插入分号。
当从左到右解析源文本时,遇到语法的某些产生式允许的标记,但该产生式是受限产生式 ,并且该标记将是紧接着受限产生式中注释"[no LineTerminator
here]"之后的终结符或非终结符的第一个标记(因此这样的标记称为受限标记),并且受限标记与前一个标记之间至少有一个 LineTerminator 分隔,则在受限标记之前自动插入分号。
但是,前述规则有一个额外的覆盖条件:如果分号随后会被解析为空语句,或者该分号会成为 for 语句头部中的两个分号之一(参见 14.7.4 ),则永远不会自动插入分号。
注
以下是语法中唯一的受限产生式:
UpdateExpression [Yield,
Await] :
LeftHandSideExpression [?Yield,
?Await]
[no LineTerminator
here]
++
LeftHandSideExpression [?Yield,
?Await]
[no LineTerminator
here]
--
ContinueStatement [Yield,
Await] :
continue
;
continue
[no LineTerminator
here]
LabelIdentifier [?Yield,
?Await]
;
BreakStatement [Yield,
Await] :
break
;
break
[no LineTerminator
here]
LabelIdentifier [?Yield,
?Await]
;
ReturnStatement [Yield,
Await] :
return
;
return
[no LineTerminator
here]
Expression [+In,
?Yield, ?Await]
;
ThrowStatement [Yield,
Await] :
throw
[no LineTerminator
here]
Expression [+In,
?Yield, ?Await]
;
YieldExpression [In,
Await] :
yield
yield
[no LineTerminator
here]
AssignmentExpression [?In,
+Yield, ?Await]
yield
[no LineTerminator
here]
*
AssignmentExpression [?In,
+Yield, ?Await]
ArrowFunction [In,
Yield, Await] :
ArrowParameters [?Yield,
?Await]
[no LineTerminator
here]
=>
ConciseBody [?In]
AsyncFunctionDeclaration [Yield,
Await, Default] :
async
[no LineTerminator
here]
function
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
[+Default]
async
[no LineTerminator
here]
function
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncFunctionExpression
:
async
[no LineTerminator
here]
function
BindingIdentifier [~Yield,
+Await] opt
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncMethod [Yield,
Await] :
async
[no LineTerminator
here]
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncGeneratorDeclaration [Yield,
Await, Default] :
async
[no LineTerminator
here]
function
*
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
[+Default]
async
[no LineTerminator
here]
function
*
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorExpression
:
async
[no LineTerminator
here]
function
*
BindingIdentifier [+Yield,
+Await] opt
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorMethod [Yield,
Await] :
async
[no LineTerminator
here]
*
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncArrowFunction [In,
Yield, Await] :
async
[no LineTerminator
here]
AsyncArrowBindingIdentifier [?Yield]
[no LineTerminator
here]
=>
AsyncConciseBody [?In]
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
[no LineTerminator
here]
=>
AsyncConciseBody [?In]
AsyncArrowHead
:
async
[no LineTerminator
here]
ArrowFormalParameters [~Yield,
+Await]
这些受限产生式的实际效果如下:
当遇到 ++ 或 -- 标记时,解析器会将其视为后缀运算符,如果在前一个标记和 ++ 或
-- 标记之间至少有一个 LineTerminator ,则在 ++ 或
-- 标记之前自动插入分号。
当遇到 continue、break、return、throw
或 yield 标记,并且在下一个标记之前遇到 LineTerminator 时,在
continue、break、return、throw 或
yield 标记之后自动插入分号。
当箭头函数参数后面在 => 标记之前有 LineTerminator
时,自动插入分号,标点符号会导致语法错误。
当 async 标记后面在 function 或 IdentifierName 或 (
标记之前有 LineTerminator
时,自动插入分号,async 标记不被视为与后续标记相同表达式或类元素的一部分。
当 async 标记后面在 * 标记之前有 LineTerminator
时,自动插入分号,标点符号会导致语法错误。
给 ECMAScript 程序员的实际建议是:
后缀 ++ 或 -- 运算符应该与其操作数在同一行。
return 或 throw 语句中的 Expression 或 yield 表达式中的
AssignmentExpression 应该与
return、throw 或 yield 标记在同一行开始。
break 或 continue 语句中的 LabelIdentifier 应该与
break 或 continue 标记在同一行。
箭头函数参数的结尾和其 => 应该在同一行。
异步函数或方法前面的 async 标记应该与紧接着的标记在同一行。
12.10.2 自动分号插入示例
本节是非规范性的。
源代码
{ 1 2 } 3
不是 ECMAScript 语法中的有效句子,即使有自动分号插入规则。相反,源代码
{ 1
2 } 3
也不是有效的 ECMAScript 句子,但通过自动分号插入转换为以下内容:
{ 1
;2 ;} 3 ;
这是一个有效的 ECMAScript 句子。
源代码
for (a; b
)
不是有效的 ECMAScript 句子,并且不会被自动分号插入更改,因为 for 语句的头部需要分号。自动分号插入永远不会插入 for
语句头部中的两个分号之一。
源代码
return
a + b
通过自动分号插入转换为以下内容:
return ;
a + b;
注 1
表达式 a + b 不被视为 return 语句要返回的值,因为 LineTerminator 将其与标记
return 分开。
源代码
a = b
++c
通过自动分号插入转换为以下内容:
a = b;
++c;
注 2
标记 ++ 不被视为应用于变量 b 的后缀运算符,因为 LineTerminator 出现在 b 和
++ 之间。
源代码
if (a > b)
else c = d
不是有效的 ECMAScript 句子,并且不会被自动分号插入在 else 标记之前更改,即使在该点语法的任何产生式都不适用,因为自动插入的分号随后会被解析为空语句。
源代码
a = b + c
(d + e).print ()
不会 被自动分号插入转换,因为第二行开始的括号表达式可以被解释为函数调用的参数列表:
a = b + c (d + e).print ()
在赋值语句必须以左括号开始的情况下,程序员最好在前一个语句的末尾提供显式分号,而不是依赖自动分号插入。
12.10.3 自动分号插入的有趣情况
本节是非规范性的。
ECMAScript 程序可以通过依赖自动分号插入以很少分号的风格编写。如上所述,分号不会在每个换行符处插入,自动分号插入可能依赖于跨行终止符的多个标记。
随着新的语法特性被添加到 ECMAScript 中,可能会添加额外的语法产生式,这些产生式会导致依赖自动分号插入的行在解析时改变语法产生式。
就本节而言,如果自动分号插入的情况是可能插入或不插入分号的地方,取决于其前面的源文本,则被认为是有趣的。本节的其余部分描述了这个版本的 ECMAScript 中自动分号插入的许多有趣情况。
12.10.3.1 语句列表中自动分号插入的有趣情况
在 StatementList 中,许多
StatementListItem
以分号结尾,这些分号可以使用自动分号插入省略。根据上述规则,在结束表达式的行末尾,如果下一行以以下任何内容开始,则需要分号:
12.10.3.2 自动分号插入和"[no LineTerminator here]"的情况
本节是非规范性的。
ECMAScript 包含包括"[no LineTerminator
here]"的语法产生式。这些产生式有时是在语法中拥有可选操作数的手段。在这些位置引入 LineTerminator
会通过使用没有可选操作数的语法产生式来改变源文本的语法产生式。
本节的其余部分描述了这个版本的 ECMAScript 中使用"[no LineTerminator here]"的许多产生式。
12.10.3.2.1 带有可选操作数和"[no LineTerminator here]"的语法产生式列表
13 ECMAScript 语言:表达式
13.1 标识符
语法
IdentifierReference [Yield,
Await] :
Identifier
[~Yield]
yield
[~Await]
await
BindingIdentifier [Yield,
Await] :
Identifier
yield
await
LabelIdentifier [Yield,
Await] :
Identifier
[~Yield]
yield
[~Await]
await
Identifier :
IdentifierName
but not ReservedWord
注
yield 和 await 在语法中被允许作为 BindingIdentifier ,并在下面的静态语义 中被禁止,以防止在以下情况中自动分号插入
let
await 0 ;
13.1.1 静态语义:早期错误
BindingIdentifier
: Identifier
IdentifierReference
: yield
BindingIdentifier
: yield
LabelIdentifier :
yield
如果 IsStrict (this production) 是
true ,则是语法错误。
IdentifierReference
: await
BindingIdentifier
: await
LabelIdentifier :
await
BindingIdentifier [Yield,
Await] : yield
如果此产生式有 [Yield] 参数,则是语法错误。
BindingIdentifier [Yield,
Await] : await
如果此产生式有 [Await] 参数,则是语法错误。
IdentifierReference [Yield,
Await] : Identifier
BindingIdentifier [Yield,
Await] : Identifier
LabelIdentifier [Yield,
Await] : Identifier
Identifier : IdentifierName but not
ReservedWord
注
13.1.2 静态语义:StringValue
语法导向操作
StringValue 不接受参数并返回 String。它在以下产生式上分段定义:
IdentifierName ::
IdentifierStart
IdentifierName
IdentifierPart
令 idTextUnescaped 为 IdentifierName 的 IdentifierCodePoints 。
返回 CodePointsToString (idTextUnescaped )。
IdentifierReference
: yield
BindingIdentifier
: yield
LabelIdentifier :
yield
返回 "yield" 。
IdentifierReference
: await
BindingIdentifier
: await
LabelIdentifier :
await
返回 "await" 。
Identifier : IdentifierName but not
ReservedWord
返回 IdentifierName 的
StringValue 。
PrivateIdentifier
::
#
IdentifierName
返回 0x0023(数字符号)与 IdentifierName 的 StringValue 的 字符串连接 。
ModuleExportName :
StringLiteral
返回 StringLiteral 的
SV 。
13.1.3 运行时语义:Evaluation
IdentifierReference
: Identifier
返回 ? ResolveBinding (Identifier 的 StringValue )。
IdentifierReference
: yield
返回 ? ResolveBinding ("yield" )。
IdentifierReference
: await
返回 ? ResolveBinding ("await" )。
注 1
求值 IdentifierReference 的结果总是
Reference 类型的值。
注 2
在非严格代码 中,关键字
yield 可以用作标识符。求值 IdentifierReference
解析 yield 的绑定,就像它是 Identifier 一样。早期错误限制确保这种求值只能在非严格代码 中发生。
13.2 主表达式
语法
PrimaryExpression [Yield,
Await] :
this
IdentifierReference [?Yield,
?Await]
Literal
ArrayLiteral [?Yield,
?Await]
ObjectLiteral [?Yield,
?Await]
FunctionExpression
ClassExpression [?Yield,
?Await]
GeneratorExpression
AsyncFunctionExpression
AsyncGeneratorExpression
RegularExpressionLiteral
TemplateLiteral [?Yield,
?Await, ~Tagged]
CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
CoverParenthesizedExpressionAndArrowParameterList [Yield,
Await] :
(
Expression [+In, ?Yield,
?Await]
)
(
Expression [+In, ?Yield,
?Await]
,
)
(
)
(
...
BindingIdentifier [?Yield,
?Await]
)
(
...
BindingPattern [?Yield,
?Await]
)
(
Expression [+In, ?Yield,
?Await]
,
...
BindingIdentifier [?Yield,
?Await]
)
(
Expression [+In, ?Yield,
?Await]
,
...
BindingPattern [?Yield,
?Await]
)
补充语法
当处理产生式的实例时
PrimaryExpression [Yield,
Await] : CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
对 CoverParenthesizedExpressionAndArrowParameterList
的解释使用以下语法进行细化:
ParenthesizedExpression [Yield,
Await] :
(
Expression [+In, ?Yield,
?Await]
)
13.2.1 this 关键字
13.2.1.1 运行时语义:Evaluation
PrimaryExpression
: this
返回 ? ResolveThisBinding ()。
13.2.2 标识符引用
关于 IdentifierReference ,请参见 13.1 。
13.2.3 字面量
语法
Literal :
NullLiteral
BooleanLiteral
NumericLiteral
StringLiteral
13.2.3.1 运行时语义:Evaluation
Literal : NullLiteral
返回 null 。
Literal : BooleanLiteral
如果 BooleanLiteral 是标记
false,返回 false 。
如果 BooleanLiteral 是标记
true,返回 true 。
Literal : NumericLiteral
返回 NumericLiteral 的 NumericValue ,如 12.9.3 中定义。
Literal : StringLiteral
返回 StringLiteral
的 SV ,如 12.9.4.2 中定义。
13.2.4 数组初始化器
注
ArrayLiteral
是一个表达式,描述使用零个或多个表达式的列表来初始化数组,每个表达式代表一个数组元素,包含在方括号中。元素不需要是字面量;每次求值数组初始化器时都会对它们进行求值。
数组元素可以在元素列表的开头、中间或末尾省略。当元素列表中的逗号前面没有 AssignmentExpression (即开头的逗号或另一个逗号后面的逗号)时,缺失的数组元素会增加数组的长度并增加后续元素的索引。省略的数组元素未定义。如果在数组末尾省略了元素,该元素不会增加数组的长度。
语法
ArrayLiteral [Yield,
Await] :
[
Elision opt
]
[
ElementList [?Yield,
?Await]
]
[
ElementList [?Yield,
?Await]
,
Elision opt
]
ElementList [Yield,
Await] :
Elision opt
AssignmentExpression [+In,
?Yield, ?Await]
Elision opt
SpreadElement [?Yield,
?Await]
ElementList [?Yield,
?Await]
,
Elision opt
AssignmentExpression [+In,
?Yield, ?Await]
ElementList [?Yield,
?Await]
,
Elision opt
SpreadElement [?Yield,
?Await]
Elision :
,
Elision
,
SpreadElement [Yield,
Await] :
...
AssignmentExpression [+In,
?Yield, ?Await]
13.2.4.1 运行时语义:ArrayAccumulation
语法导向操作
ArrayAccumulation 接受参数 array (一个数组)和 nextIndex (一个整数 )并返回包含 一个整数 的正常完成 或一个突然完成 。它在以下产生式上分段定义:
Elision : ,
令 len 为 nextIndex + 1。
执行 ? Set (array ,
"length" , 𝔽 (len ), true )。
注:如果 len 超过 232 - 1,上述步骤会抛出异常。
返回 len 。
Elision :
Elision
,
返回 ? Elision 与参数
array 和 (nextIndex + 1) 的 ArrayAccumulation 。
ElementList :
Elision opt
AssignmentExpression
如果 Elision 存在,则
设置 nextIndex 为 ? Elision 与参数 array 和
nextIndex 的 ArrayAccumulation 。
令 initResult 为 ? AssignmentExpression 的
Evaluation 。
令 initValue 为 ? GetValue (initResult )。
执行 ! CreateDataPropertyOrThrow (array ,
! ToString (𝔽 (nextIndex )),
initValue )。
返回 nextIndex + 1。
ElementList :
Elision opt
SpreadElement
如果 Elision 存在,则
设置 nextIndex 为 ? Elision 与参数 array 和
nextIndex 的 ArrayAccumulation 。
返回 ? SpreadElement 与参数 array 和
nextIndex 的 ArrayAccumulation 。
ElementList :
ElementList
,
Elision opt
AssignmentExpression
设置 nextIndex 为 ? ElementList 与参数 array 和
nextIndex 的 ArrayAccumulation 。
如果 Elision 存在,则
设置 nextIndex 为 ? Elision 与参数 array 和
nextIndex 的 ArrayAccumulation 。
令 initResult 为 ? AssignmentExpression 的
Evaluation 。
令 initValue 为 ? GetValue (initResult )。
执行 ! CreateDataPropertyOrThrow (array ,
! ToString (𝔽 (nextIndex )),
initValue )。
返回 nextIndex + 1。
ElementList :
ElementList
,
Elision opt
SpreadElement
设置 nextIndex 为 ? ElementList 与参数 array 和
nextIndex 的 ArrayAccumulation 。
如果 Elision 存在,则
设置 nextIndex 为 ? Elision 与参数 array 和
nextIndex 的 ArrayAccumulation 。
返回 ? SpreadElement 与参数 array 和
nextIndex 的 ArrayAccumulation 。
SpreadElement :
...
AssignmentExpression
令 spreadRef 为 ? AssignmentExpression 的
Evaluation 。
令 spreadObj 为 ? GetValue (spreadRef )。
令 iteratorRecord 为 ? GetIterator (spreadObj ,
sync )。
重复,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,返回
nextIndex 。
执行 ! CreateDataPropertyOrThrow (array ,
! ToString (𝔽 (nextIndex )),
next )。
设置 nextIndex 为 nextIndex + 1。
注
使用 CreateDataPropertyOrThrow
来确保为数组定义自己的属性,即使标准内置的Array
原型对象 已经以会阻止使用 [[Set]] 创建新自己属性的方式被修改。
13.2.4.2 运行时语义:Evaluation
ArrayLiteral :
[
Elision opt
]
令 array 为 ! ArrayCreate (0)。
如果 Elision 存在,则
执行 ? Elision 与参数 array 和 0 的
ArrayAccumulation 。
返回 array 。
ArrayLiteral :
[
ElementList
]
令 array 为 ! ArrayCreate (0)。
执行 ? ElementList 与参数 array 和 0 的
ArrayAccumulation 。
返回 array 。
ArrayLiteral :
[
ElementList
,
Elision opt
]
令 array 为 ! ArrayCreate (0)。
令 nextIndex 为 ? ElementList 与参数 array 和 0 的
ArrayAccumulation 。
如果 Elision 存在,则
执行 ? Elision 与参数 array 和
nextIndex 的 ArrayAccumulation 。
返回 array 。
13.2.5 对象初始化器
注 1
对象初始化器是一个表达式,描述对象的初始化,以类似字面量的形式编写。它是零个或多个属性键 和关联值的对的列表,包含在花括号中。值不需要是字面量;每次求值对象初始化器时都会对它们进行求值。
语法
ObjectLiteral [Yield,
Await] :
{
}
{
PropertyDefinitionList [?Yield,
?Await]
}
{
PropertyDefinitionList [?Yield,
?Await]
,
}
PropertyDefinitionList [Yield,
Await] :
PropertyDefinition [?Yield,
?Await]
PropertyDefinitionList [?Yield,
?Await]
,
PropertyDefinition [?Yield,
?Await]
PropertyDefinition [Yield,
Await] :
IdentifierReference [?Yield,
?Await]
CoverInitializedName [?Yield,
?Await]
PropertyName [?Yield,
?Await]
:
AssignmentExpression [+In,
?Yield, ?Await]
MethodDefinition [?Yield,
?Await]
...
AssignmentExpression [+In,
?Yield, ?Await]
PropertyName [Yield,
Await] :
LiteralPropertyName
ComputedPropertyName [?Yield,
?Await]
LiteralPropertyName
:
IdentifierName
StringLiteral
NumericLiteral
ComputedPropertyName [Yield,
Await] :
[
AssignmentExpression [+In,
?Yield, ?Await]
]
CoverInitializedName [Yield,
Await] :
IdentifierReference [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await]
Initializer [In, Yield,
Await] :
=
AssignmentExpression [?In,
?Yield, ?Await]
注 2
注 3
在某些上下文中,ObjectLiteral
用作更受限制的次级语法的覆盖语法。CoverInitializedName
产生式是完全覆盖这些次级语法所必需的。但是,在期望实际 ObjectLiteral 的正常上下文中,使用此产生式会导致早期语法错误。
13.2.5.1 静态语义:早期错误
PropertyDefinition
: MethodDefinition
除了描述实际的对象初始化器之外,ObjectLiteral 产生式还用作 ObjectAssignmentPattern
的覆盖语法,并且可能被识别为 CoverParenthesizedExpressionAndArrowParameterList
的一部分。当 ObjectLiteral
出现在需要 ObjectAssignmentPattern
的上下文中时,以下早期错误规则不 适用。此外,在最初解析 CoverParenthesizedExpressionAndArrowParameterList
或 CoverCallExpressionAndAsyncArrowHead
时,它们也不适用。
PropertyDefinition
: CoverInitializedName
注 1
此产生式的存在是为了让 ObjectLiteral 可以作为 ObjectAssignmentPattern
的覆盖语法。它不能出现在实际的对象初始化器中。
ObjectLiteral :
{
PropertyDefinitionList
}
{
PropertyDefinitionList
,
}
注 2
13.2.5.2 静态语义:IsComputedPropertyKey
语法导向操作
IsComputedPropertyKey 不接受参数并返回布尔值。它在以下产生式上分段定义:
PropertyName :
LiteralPropertyName
返回 false 。
PropertyName :
ComputedPropertyName
返回 true 。
13.2.5.3 静态语义:PropertyNameList
语法导向操作
PropertyNameList 不接受参数并返回字符串的列表 。它在以下产生式上分段定义:
PropertyDefinitionList
: PropertyDefinition
令 propName 为 PropertyDefinition 的 PropName 。
如果 propName 是 empty ,返回新的空列表 。
返回 « propName »。
PropertyDefinitionList
:
PropertyDefinitionList
,
PropertyDefinition
令 list 为 PropertyDefinitionList 的
PropertyNameList 。
令 propName 为 PropertyDefinition 的 PropName 。
如果 propName 是 empty ,返回 list 。
返回 list 和 « propName » 的列表连接 。
13.2.5.4 运行时语义:Evaluation
ObjectLiteral :
{
}
返回 OrdinaryObjectCreate (%Object.prototype% )。
ObjectLiteral :
{
PropertyDefinitionList
}
{
PropertyDefinitionList
,
}
令 obj 为 OrdinaryObjectCreate (%Object.prototype% )。
执行 ? PropertyDefinitionList 与参数
obj 的 PropertyDefinitionEvaluation 。
返回 obj 。
LiteralPropertyName
: IdentifierName
返回 IdentifierName 的 StringValue 。
LiteralPropertyName
: StringLiteral
返回 StringLiteral
的 SV 。
LiteralPropertyName
: NumericLiteral
令 nbr 为 NumericLiteral 的 NumericValue 。
返回 ! ToString (nbr )。
ComputedPropertyName
:
[
AssignmentExpression
]
令 exprValue 为 ? AssignmentExpression 的
Evaluation 。
令 propName 为 ? GetValue (exprValue )。
返回 ? ToPropertyKey (propName )。
13.2.5.5 运行时语义:PropertyDefinitionEvaluation
语法导向操作
PropertyDefinitionEvaluation 接受参数 object (一个对象)并返回包含
unused 的正常完成 或突然完成 。它在以下产生式上分段定义:
PropertyDefinitionList
:
PropertyDefinitionList
,
PropertyDefinition
执行 ? PropertyDefinitionList 与参数
object 的 PropertyDefinitionEvaluation 。
执行 ? PropertyDefinition 与参数
object 的 PropertyDefinitionEvaluation 。
返回 unused 。
PropertyDefinition
:
...
AssignmentExpression
令 exprValue 为 ? AssignmentExpression 的
Evaluation 。
令 fromValue 为 ? GetValue (exprValue )。
令 excludedNames 为新的空列表 。
执行 ? CopyDataProperties (object ,
fromValue , excludedNames )。
返回 unused 。
PropertyDefinition
: IdentifierReference
令 propName 为 IdentifierReference 的
StringValue 。
令 exprValue 为 ? IdentifierReference 的
Evaluation 。
令 propValue 为 ? GetValue (exprValue )。
断言 :
object 是一个普通的、可扩展的、没有不可配置属性的对象。
执行 ! CreateDataPropertyOrThrow (object ,
propName , propValue )。
返回 unused 。
PropertyDefinition
:
PropertyName
:
AssignmentExpression
令 propKey 为 ? PropertyName 的 Evaluation 。
如果此 PropertyDefinition 包含在正在为
ParseJSON 求值的 Script 中(参见 ParseJSON 的步骤 6 ),则
令 isProtoSetter 为 false 。
否则,如果 propKey 是 "__proto__" 并且 PropertyName 的
IsComputedPropertyKey
是 false ,则
令 isProtoSetter 为 true 。
否则,
令 isProtoSetter 为 false 。
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 是
true 并且 isProtoSetter 是 false ,则
令 propValue 为 ? AssignmentExpression
与参数 propKey 的 NamedEvaluation 。
否则,
令 exprValueRef 为 ? AssignmentExpression
的 Evaluation 。
令 propValue 为 ? GetValue (exprValueRef )。
如果 isProtoSetter 是 true ,则
如果 propValue 是对象 或 propValue 是
null ,则
执行 ! object .[[SetPrototypeOf]] (propValue )。
返回 unused 。
断言 :
object 是一个普通的、可扩展的、没有不可配置属性的对象。
执行 ! CreateDataPropertyOrThrow (object ,
propKey , propValue )。
返回 unused 。
PropertyDefinition
: MethodDefinition
执行 ? MethodDefinition 与参数
object 和 true 的 MethodDefinitionEvaluation 。
返回 unused 。
13.2.6 函数定义表达式
有关
PrimaryExpression
: FunctionExpression
,参见 15.2 。
有关
PrimaryExpression
: GeneratorExpression
,参见 15.5 。
有关
PrimaryExpression
: ClassExpression
,参见 15.7 。
有关
PrimaryExpression
: AsyncFunctionExpression
,参见 15.8 。
有关
PrimaryExpression
: AsyncGeneratorExpression
,参见 15.6 。
13.2.7 正则表达式字面量
语法
参见 12.9.5 。
13.2.7.1 静态语义:早期错误
PrimaryExpression
: RegularExpressionLiteral
13.2.7.2 静态语义:IsValidRegularExpressionLiteral (
literal )
抽象操作 IsValidRegularExpressionLiteral 接受参数 literal (一个 RegularExpressionLiteral
解析节点 )并返回布尔值。它确定其参数是否是有效的正则表达式字面量。调用时执行以下步骤:
令 flags 为 literal 的 FlagText 。
如果 flags 包含除
d、g、i、m、s、u、v
或 y 之外的任何码点,或者如果 flags 包含任何码点超过一次,返回
false 。
如果 flags 包含 u,令 u 为 true ;否则令
u 为 false 。
如果 flags 包含 v,令 v 为 true ;否则令
v 为 false 。
令 patternText 为 literal 的 BodyText 。
如果 u 是 false 且 v 是
false ,则
令 stringValue 为 CodePointsToString (patternText )。
设置 patternText 为通过将 stringValue 的每个 16 位元素解释为 Unicode
BMP 码点而产生的码点序列。UTF-16 解码不应用于这些元素。
令 parseResult 为 ParsePattern (patternText ,
u , v )。
如果 parseResult 是解析节点 ,返回
true ;否则返回 false 。
13.2.7.3 运行时语义:Evaluation
PrimaryExpression
: RegularExpressionLiteral
令 pattern 为 CodePointsToString (RegularExpressionLiteral
的 BodyText )。
令 flags 为 CodePointsToString (RegularExpressionLiteral
的 FlagText )。
返回 ! RegExpCreate (pattern ,
flags )。
13.2.8 模板字面量
语法
TemplateLiteral [Yield, Await,
Tagged] :
NoSubstitutionTemplate
SubstitutionTemplate [?Yield,
?Await, ?Tagged]
SubstitutionTemplate [Yield,
Await, Tagged] :
TemplateHead
Expression [+In, ?Yield,
?Await]
TemplateSpans [?Yield,
?Await, ?Tagged]
TemplateSpans [Yield, Await,
Tagged] :
TemplateTail
TemplateMiddleList [?Yield,
?Await, ?Tagged]
TemplateTail
TemplateMiddleList [Yield,
Await, Tagged] :
TemplateMiddle
Expression [+In, ?Yield,
?Await]
TemplateMiddleList [?Yield,
?Await, ?Tagged]
TemplateMiddle
Expression [+In, ?Yield,
?Await]
13.2.8.1 静态语义:早期错误
TemplateLiteral [Yield,
Await, Tagged] :
NoSubstitutionTemplate
TemplateLiteral [Yield,
Await, Tagged] :
SubstitutionTemplate [?Yield,
?Await, ?Tagged]
SubstitutionTemplate [Yield,
Await, Tagged] :
TemplateHead
Expression [+In, ?Yield,
?Await]
TemplateSpans [?Yield,
?Await, ?Tagged]
TemplateSpans [Yield, Await,
Tagged] : TemplateTail
TemplateMiddleList [Yield,
Await, Tagged] :
TemplateMiddle
Expression [+In, ?Yield,
?Await]
TemplateMiddleList [?Yield,
?Await, ?Tagged]
TemplateMiddle
Expression [+In, ?Yield,
?Await]
13.2.8.2 静态语义:TemplateStrings
语法导向操作
TemplateStrings 接受参数 raw (布尔值)并返回字符串或 undefined 的列表 。它在以下产生式上分段定义:
TemplateLiteral
: NoSubstitutionTemplate
返回 « TemplateString (NoSubstitutionTemplate ,
raw ) »。
SubstitutionTemplate
:
TemplateHead
Expression
TemplateSpans
令 head 为 « TemplateString (TemplateHead ,
raw ) »。
令 tail 为 TemplateSpans 使用参数 raw 的
TemplateStrings 。
返回 head 和 tail 的列表连接 。
TemplateSpans :
TemplateTail
返回 « TemplateString (TemplateTail ,
raw ) »。
TemplateSpans :
TemplateMiddleList
TemplateTail
令 middle 为 TemplateMiddleList 使用参数
raw 的 TemplateStrings 。
令 tail 为 « TemplateString (TemplateTail ,
raw ) »。
返回 middle 和 tail 的列表连接 。
TemplateMiddleList
:
TemplateMiddle
Expression
返回 « TemplateString (TemplateMiddle ,
raw ) »。
TemplateMiddleList
:
TemplateMiddleList
TemplateMiddle
Expression
令 front 为 TemplateMiddleList 使用参数
raw 的 TemplateStrings 。
令 last 为 « TemplateString (TemplateMiddle ,
raw ) »。
返回 front 和 last 的列表连接 。
13.2.8.3 静态语义:TemplateString ( templateToken ,
raw )
抽象操作 TemplateString 接受参数 templateToken (一个 NoSubstitutionTemplate 解析节点 、TemplateHead 解析节点 、TemplateMiddle 解析节点 ,或 TemplateTail 解析节点 )和 raw (布尔值)并返回字符串或
undefined 。调用时执行以下步骤:
如果 raw 是 true ,则
令 string 为 templateToken 的 TRV 。
否则,
令 string 为 templateToken 的 TV 。
返回 string 。
注
如果 raw 是 false 且 templateToken 包含 NotEscapeSequence ,此操作返回
undefined 。在所有其他情况下,它返回字符串。
13.2.8.4 GetTemplateObject ( templateLiteral )
抽象操作 GetTemplateObject 接受参数 templateLiteral (一个解析节点 )并返回数组。调用时执行以下步骤:
令 realm 为当前领域记录 。
令 templateRegistry 为 realm .[[TemplateMap]] 。
对于 templateRegistry 的每个元素 e ,执行
如果 e .[[Site]] 与
templateLiteral 是同一个解析节点 ,则
返回 e .[[Array]] 。
令 rawStrings 为 templateLiteral 使用参数 true 的
TemplateStrings 。
断言 :rawStrings 是字符串的列表 。
令 cookedStrings 为 templateLiteral 使用参数
false 的 TemplateStrings 。
令 count 为列表
cookedStrings 中的元素数量。
断言 :count ≤ 232 - 1。
令 template 为 ! ArrayCreate (count )。
令 rawObj 为 ! ArrayCreate (count )。
令 index 为 0。
重复,当 index < count 时,
令 prop 为 ! ToString (𝔽 (index ))。
令 cookedValue 为 cookedStrings [index ]。
执行 ! DefinePropertyOrThrow (template ,
prop , PropertyDescriptor { [[Value]] :
cookedValue , [[Writable]] :
false , [[Enumerable]] :
true , [[Configurable]] :
false })。
令 rawValue 为字符串值 rawStrings [index ]。
执行 ! DefinePropertyOrThrow (rawObj ,
prop , PropertyDescriptor { [[Value]] :
rawValue , [[Writable]] :
false , [[Enumerable]] :
true , [[Configurable]] :
false })。
设置 index 为 index + 1。
执行 ! SetIntegrityLevel (rawObj ,
frozen )。
执行 ! DefinePropertyOrThrow (template ,
"raw" , PropertyDescriptor { [[Value]] :
rawObj , [[Writable]] : false ,
[[Enumerable]] : false , [[Configurable]] : false })。
执行 ! SetIntegrityLevel (template ,
frozen )。
将记录 { [[Site]] : templateLiteral , [[Array]] : template } 附加到
realm .[[TemplateMap]] 。
返回 template 。
注 1
注 2
领域 程序代码中的每个
TemplateLiteral
都与一个唯一的模板对象相关联,该对象用于带标签模板的求值(13.2.8.6 )。模板对象被冻结,每次求值特定带标签模板时都使用相同的模板对象。模板对象是在首次求值
TemplateLiteral
时惰性创建,还是在首次求值前急切创建,是实现选择,ECMAScript 代码无法观察到。
注 3
本规范的未来版本可能定义模板对象的附加不可枚举属性。
13.2.8.5 运行时语义:SubstitutionEvaluation
语法导向操作
SubstitutionEvaluation 不接受参数并返回包含
ECMAScript 语言值 的列表 的正常完成 或突然完成 。它在以下产生式上分段定义:
TemplateSpans :
TemplateTail
返回新的空列表 。
TemplateSpans :
TemplateMiddleList
TemplateTail
返回 ? TemplateMiddleList 的 SubstitutionEvaluation 。
TemplateMiddleList
:
TemplateMiddle
Expression
令 subRef 为 ? Expression 的 Evaluation 。
令 sub 为 ? GetValue (subRef )。
返回 « sub »。
TemplateMiddleList
:
TemplateMiddleList
TemplateMiddle
Expression
令 preceding 为 ? TemplateMiddleList 的 SubstitutionEvaluation 。
令 nextRef 为 ? Expression 的 Evaluation 。
令 next 为 ? GetValue (nextRef )。
返回 preceding 和 « next » 的列表连接 。
13.2.8.6 运行时语义:Evaluation
TemplateLiteral
: NoSubstitutionTemplate
返回 NoSubstitutionTemplate 的
TV ,如 12.9.6 中定义。
SubstitutionTemplate
:
TemplateHead
Expression
TemplateSpans
令 head 为 TemplateHead 的 TV ,如 12.9.6 中定义。
令 subRef 为 ? Expression 的 Evaluation 。
令 sub 为 ? GetValue (subRef )。
令 middle 为 ? ToString (sub )。
令 tail 为 ? TemplateSpans 的 Evaluation 。
返回 head 、middle 和 tail 的字符串连接 。
注 1
应用于 Expression
值的字符串转换语义类似于 String.prototype.concat 而不是 + 运算符。
TemplateSpans :
TemplateTail
返回 TemplateTail 的
TV ,如 12.9.6 中定义。
TemplateSpans :
TemplateMiddleList
TemplateTail
令 head 为 ? TemplateMiddleList 的 Evaluation 。
令 tail 为 TemplateTail 的 TV ,如 12.9.6 中定义。
返回 head 和 tail 的字符串连接 。
TemplateMiddleList
:
TemplateMiddle
Expression
令 head 为 TemplateMiddle 的 TV ,如
12.9.6 中定义。
令 subRef 为 ? Expression 的 Evaluation 。
令 sub 为 ? GetValue (subRef )。
令 middle 为 ? ToString (sub )。
返回 head 和 middle 的字符串连接 。
注 2
应用于 Expression
值的字符串转换语义类似于 String.prototype.concat 而不是 + 运算符。
TemplateMiddleList
:
TemplateMiddleList
TemplateMiddle
Expression
令 rest 为 ? TemplateMiddleList 的 Evaluation 。
令 middle 为 TemplateMiddle 的 TV ,如
12.9.6 中定义。
令 subRef 为 ? Expression 的 Evaluation 。
令 sub 为 ? GetValue (subRef )。
令 last 为 ? ToString (sub )。
返回 rest 、middle 和 last 的字符串连接 。
注 3
应用于 Expression
值的字符串转换语义类似于 String.prototype.concat 而不是 + 运算符。
13.2.9 分组运算符
13.2.9.1 静态语义:早期错误
PrimaryExpression
: CoverParenthesizedExpressionAndArrowParameterList
13.2.9.2 运行时语义:Evaluation
PrimaryExpression
: CoverParenthesizedExpressionAndArrowParameterList
令 expr 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ParenthesizedExpression 。
返回 ? expr 的 Evaluation 。
ParenthesizedExpression
:
(
Expression
)
返回 ? Expression
的 Evaluation 。这可能是引用类型。
注
此算法不对 Expression 的
Evaluation 应用 GetValue 。这样做的主要动机是使 delete
和 typeof 等运算符可以应用于带括号的表达式。
13.3 左值表达式
语法
MemberExpression [Yield,
Await] :
PrimaryExpression [?Yield,
?Await]
MemberExpression [?Yield,
?Await]
[
Expression [+In, ?Yield,
?Await]
]
MemberExpression [?Yield,
?Await]
.
IdentifierName
MemberExpression [?Yield,
?Await]
TemplateLiteral [?Yield,
?Await, +Tagged]
SuperProperty [?Yield,
?Await]
MetaProperty
new
MemberExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
MemberExpression [?Yield,
?Await]
.
PrivateIdentifier
SuperProperty [Yield,
Await] :
super
[
Expression [+In, ?Yield,
?Await]
]
super
.
IdentifierName
MetaProperty :
NewTarget
ImportMeta
NewTarget :
new
.
target
ImportMeta :
import
.
meta
NewExpression [Yield,
Await] :
MemberExpression [?Yield,
?Await]
new
NewExpression [?Yield,
?Await]
CallExpression [Yield,
Await] :
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
SuperCall [?Yield,
?Await]
ImportCall [?Yield,
?Await]
CallExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
CallExpression [?Yield,
?Await]
[
Expression [+In, ?Yield,
?Await]
]
CallExpression [?Yield,
?Await]
.
IdentifierName
CallExpression [?Yield,
?Await]
TemplateLiteral [?Yield,
?Await, +Tagged]
CallExpression [?Yield,
?Await]
.
PrivateIdentifier
SuperCall [Yield,
Await] :
super
Arguments [?Yield,
?Await]
ImportCall [Yield,
Await] :
import
(
AssignmentExpression [+In,
?Yield, ?Await]
,opt
)
import
(
AssignmentExpression [+In,
?Yield, ?Await]
,
AssignmentExpression [+In,
?Yield, ?Await]
,opt
)
Arguments [Yield,
Await] :
(
)
(
ArgumentList [?Yield,
?Await]
)
(
ArgumentList [?Yield,
?Await]
,
)
ArgumentList [Yield,
Await] :
AssignmentExpression [+In,
?Yield, ?Await]
...
AssignmentExpression [+In,
?Yield, ?Await]
ArgumentList [?Yield,
?Await]
,
AssignmentExpression [+In,
?Yield, ?Await]
ArgumentList [?Yield,
?Await]
,
...
AssignmentExpression [+In,
?Yield, ?Await]
OptionalExpression [Yield,
Await] :
MemberExpression [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
CallExpression [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
OptionalExpression [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
OptionalChain [Yield,
Await] :
?.
Arguments [?Yield,
?Await]
?.
[
Expression [+In, ?Yield,
?Await]
]
?.
IdentifierName
?.
TemplateLiteral [?Yield,
?Await, +Tagged]
?.
PrivateIdentifier
OptionalChain [?Yield,
?Await]
Arguments [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
[
Expression [+In, ?Yield,
?Await]
]
OptionalChain [?Yield,
?Await]
.
IdentifierName
OptionalChain [?Yield,
?Await]
TemplateLiteral [?Yield,
?Await, +Tagged]
OptionalChain [?Yield,
?Await]
.
PrivateIdentifier
LeftHandSideExpression [Yield,
Await] :
NewExpression [?Yield,
?Await]
CallExpression [?Yield,
?Await]
OptionalExpression [?Yield,
?Await]
补充语法
当处理产生式的实例时
CallExpression :
CoverCallExpressionAndAsyncArrowHead
使用以下语法细化对 CoverCallExpressionAndAsyncArrowHead
的解释:
CallMemberExpression [Yield,
Await] :
MemberExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
13.3.1 静态语义
13.3.1.1 静态语义:早期错误
OptionalChain :
?.
TemplateLiteral
OptionalChain
TemplateLiteral
注
此产生式的存在是为了防止自动分号插入规则(12.10 )应用于以下代码:
a?.b
`c`
这样它就不会被解释为两个有效的语句。目的是与没有可选链的类似代码保持一致:
a.b
`c`
这是一个有效的语句,其中不应用自动分号插入。
ImportMeta :
import
.
meta
13.3.2 属性访问器
注
属性通过名称进行访问,可以使用点记法:
或括号记法:
点记法通过以下语法转换解释:
在行为上等同于
同样地
在行为上等同于
其中 <identifier-name-string > 是 IdentifierName 的 StringValue 。
13.3.2.1 运行时语义:Evaluation
MemberExpression
:
MemberExpression
[
Expression
]
令 baseReference 为 ? MemberExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
令 strict 为此 MemberExpression 的 IsStrict 。
返回 ? EvaluatePropertyAccessWithExpressionKey (baseValue ,
Expression ,
strict )。
MemberExpression
:
MemberExpression
.
IdentifierName
令 baseReference 为 ? MemberExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
令 strict 为此 MemberExpression 的 IsStrict 。
返回 EvaluatePropertyAccessWithIdentifierKey (baseValue ,
IdentifierName ,
strict )。
MemberExpression
:
MemberExpression
.
PrivateIdentifier
令 baseReference 为 ? MemberExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
令 fieldNameString 为 PrivateIdentifier 的 StringValue 。
返回 MakePrivateReference (baseValue ,
fieldNameString )。
CallExpression :
CallExpression
[
Expression
]
令 baseReference 为 ? CallExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
令 strict 为此 CallExpression 的 IsStrict 。
返回 ? EvaluatePropertyAccessWithExpressionKey (baseValue ,
Expression ,
strict )。
CallExpression :
CallExpression
.
IdentifierName
令 baseReference 为 ? CallExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
令 strict 为此 CallExpression 的 IsStrict 。
返回 EvaluatePropertyAccessWithIdentifierKey (baseValue ,
IdentifierName ,
strict )。
CallExpression :
CallExpression
.
PrivateIdentifier
令 baseReference 为 ? CallExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
令 fieldNameString 为 PrivateIdentifier 的 StringValue 。
返回 MakePrivateReference (baseValue ,
fieldNameString )。
13.3.3 EvaluatePropertyAccessWithExpressionKey (
baseValue , expression , strict )
抽象操作 EvaluatePropertyAccessWithExpressionKey 接受参数
baseValue (一个 ECMAScript 语言值 )、
expression (一个 Expression 解析节点 )和
strict (一个布尔值),返回包含
引用记录 的正常完成 或突然完成 。当调用时执行以下步骤:
令 propertyNameReference 为 ? expression 的 Evaluation 。
令 propertyNameValue 为 ? GetValue (propertyNameReference )。
注:在大多数情况下,ToPropertyKey 将在此步骤之后立即对
propertyNameValue 执行。但是,在 a[b] = c 的情况下,它将直到 c
求值之后才执行。
返回引用记录
{ [[Base]] : baseValue , [[ReferencedName]] : propertyNameValue , [[Strict]] : strict , [[ThisValue]] : empty }。
13.3.4 EvaluatePropertyAccessWithIdentifierKey (
baseValue , identifierName , strict )
抽象操作 EvaluatePropertyAccessWithIdentifierKey 接受参数
baseValue (一个 ECMAScript 语言值 )、
identifierName (一个 IdentifierName 解析节点 )和 strict (一个布尔值),返回一个
引用记录 。当调用时执行以下步骤:
令 propertyNameString 为 identifierName 的 StringValue 。
返回引用记录
{ [[Base]] : baseValue , [[ReferencedName]] : propertyNameString , [[Strict]] : strict , [[ThisValue]] : empty }。
13.3.5 new 运算符
13.3.5.1 运行时语义:Evaluation
NewExpression :
new
NewExpression
返回 ? EvaluateNew (NewExpression ,
empty )。
MemberExpression
:
new
MemberExpression
Arguments
返回 ? EvaluateNew (MemberExpression , Arguments )。
13.3.5.1.1 EvaluateNew ( constructExpr ,
arguments )
抽象操作 EvaluateNew 接受参数 constructExpr (一个 NewExpression 解析节点 或一个 MemberExpression 解析节点 )和
arguments (empty 或一个 Arguments 解析节点 ),返回包含 ECMAScript 语言值 的正常完成 或突然完成 。当调用时执行以下步骤:
令 ref 为 ? constructExpr 的 Evaluation 。
令 constructor 为 ? GetValue (ref )。
如果 arguments 是 empty ,则
令 argList 为新的空列表 。
否则,
令 argList 为 ? arguments 的 ArgumentListEvaluation 。
如果 IsConstructor (constructor )
是 false ,抛出 TypeError 异常。
返回 ? Construct (constructor ,
argList )。
13.3.6 函数调用
13.3.6.1 运行时语义:Evaluation
CallExpression :
CoverCallExpressionAndAsyncArrowHead
令 expr 为被 CoverCallExpressionAndAsyncArrowHead
覆盖 的 CallMemberExpression 。
令 memberExpr 为 expr 的 MemberExpression 。
令 arguments 为 expr 的 Arguments 。
令 ref 为 ? memberExpr 的 Evaluation 。
令 func 为 ? GetValue (ref )。
如果 ref 是引用记录 ,IsPropertyReference (ref )
是 false ,且 ref .[[ReferencedName]] 是 "eval" ,则
如果 SameValue (func ,
%eval% ) 是
true ,则
令 argList 为 ? arguments 的 ArgumentListEvaluation 。
如果 argList 没有元素,返回 undefined 。
令 evalArg 为 argList 的第一个元素。
如果此 CallExpression 的
IsStrict 是
true ,则令 strictCaller 为
true 。否则令 strictCaller 为
false 。
返回
? PerformEval (evalArg ,
strictCaller , true )。
令 thisCall 为此 CallExpression 。
令 tailCall 为 IsInTailPosition (thisCall )。
返回 ? EvaluateCall (func ,
ref , arguments , tailCall )。
执行步骤 6.a.v 的 CallExpression
求值是直接 eval 。
CallExpression :
CallExpression
Arguments
令 ref 为 ? CallExpression 的 Evaluation 。
令 func 为 ? GetValue (ref )。
令 thisCall 为此 CallExpression 。
令 tailCall 为 IsInTailPosition (thisCall )。
返回 ? EvaluateCall (func ,
ref , Arguments , tailCall )。
13.3.6.2 EvaluateCall ( func , ref ,
arguments , tailPosition )
抽象操作 EvaluateCall 接受参数 func (一个 ECMAScript 语言值 )、
ref (一个 ECMAScript 语言值 或引用记录 )、
arguments (一个 解析节点 )和
tailPosition (一个布尔值),返回包含
ECMAScript 语言值 的正常完成 或突然完成 。当调用时执行以下步骤:
如果 ref 是引用记录 ,则
如果 IsPropertyReference (ref )
是 true ,则
令 thisValue 为 GetThisValue (ref )。
否则,
令 refEnv 为 ref .[[Base]] 。
断言 :refEnv
是环境记录 。
令 thisValue 为 refEnv .WithBaseObject()。
否则,
令 thisValue 为 undefined 。
令 argList 为 ? arguments 的 ArgumentListEvaluation 。
如果 func 不是对象 ,抛出 TypeError
异常。
如果 IsCallable (func ) 是
false ,抛出 TypeError 异常。
如果 tailPosition 是 true ,执行 PrepareForTailCall ()。
返回 ? Call (func ,
thisValue , argList )。
13.3.7 super 关键字
13.3.7.1 运行时语义:Evaluation
SuperProperty :
super
[
Expression
]
令 env 为 GetThisEnvironment ()。
令 actualThis 为 ? env .GetThisBinding()。
令 propertyNameReference 为 ? Expression 的 Evaluation 。
令 propertyNameValue 为 ? GetValue (propertyNameReference )。
令 strict 为此 SuperProperty 的 IsStrict 。
注:在大多数情况下,ToPropertyKey 将在此步骤之后立即对
propertyNameValue 执行。但是,在 super[b] = c 的情况下,它将直到
c 求值之后才执行。
返回 MakeSuperPropertyReference (actualThis ,
propertyNameValue , strict )。
SuperProperty :
super
.
IdentifierName
令 env 为 GetThisEnvironment ()。
令 actualThis 为 ? env .GetThisBinding()。
令 propertyKey 为 IdentifierName 的 StringValue 。
令 strict 为此 SuperProperty 的 IsStrict 。
返回 MakeSuperPropertyReference (actualThis ,
propertyKey , strict )。
SuperCall :
super
Arguments
令 newTarget 为 GetNewTarget ()。
断言 :
newTarget 是构造器 。
令 func 为 GetSuperConstructor ()。
令 argList 为 ? Arguments 的 ArgumentListEvaluation 。
如果 IsConstructor (func ) 是
false ,抛出 TypeError 异常。
令 result 为 ? Construct (func ,
argList , newTarget )。
令 thisER 为 GetThisEnvironment ()。
断言 :
thisER 是函数环境记录 。
执行 ? BindThisValue (thisER ,
result )。
令 F 为 thisER .[[FunctionObject]] 。
断言 :
F 是 ECMAScript 函数对象 。
执行 ? InitializeInstanceElements (result ,
F )。
返回 result 。
13.3.7.2 GetSuperConstructor ( )
抽象操作 GetSuperConstructor 不接受参数,返回一个 ECMAScript
语言值 。当调用时执行以下步骤:
令 envRec 为 GetThisEnvironment ()。
断言 :
envRec 是函数环境记录 。
令 activeFunction 为 envRec .[[FunctionObject]] 。
断言 :
activeFunction 是 ECMAScript 函数对象 。
令 superConstructor 为 ! activeFunction .[[GetPrototypeOf]] ()。
返回 superConstructor 。
13.3.7.3 MakeSuperPropertyReference ( actualThis ,
propertyKey , strict )
抽象操作 MakeSuperPropertyReference 接受参数 actualThis (一个 ECMAScript 语言值 )、
propertyKey (一个 ECMAScript 语言值 )和
strict (一个布尔值),返回一个 Super 引用记录 。当调用时执行以下步骤:
令 env 为 GetThisEnvironment ()。
断言 :
env .HasSuperBinding() 是 true 。
断言 :
env 是函数环境记录 。
令 baseValue 为 GetSuperBase (env )。
返回引用记录 { [[Base]] :
baseValue , [[ReferencedName]] :
propertyKey , [[Strict]] : strict , [[ThisValue]] : actualThis }。
13.3.8 参数列表
注
13.3.8.1 运行时语义:ArgumentListEvaluation
语法制导操作
ArgumentListEvaluation 不接受参数,返回包含
ECMAScript 语言值 的 列表 的正常完成 或突然完成 。它在以下产生式上分段定义:
Arguments :
(
)
返回新的空列表 。
ArgumentList :
AssignmentExpression
令 ref 为 ? AssignmentExpression 的
Evaluation 。
令 arg 为 ? GetValue (ref )。
返回 « arg »。
ArgumentList :
...
AssignmentExpression
令 list 为新的空列表 。
令 spreadRef 为 ? AssignmentExpression 的
Evaluation 。
令 spreadObj 为 ? GetValue (spreadRef )。
令 iteratorRecord 为 ? GetIterator (spreadObj ,
sync )。
重复,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,返回 list 。
将 next 附加到 list 。
ArgumentList :
ArgumentList
,
AssignmentExpression
令 precedingArgs 为 ? ArgumentList 的 ArgumentListEvaluation 。
令 ref 为 ? AssignmentExpression 的
Evaluation 。
令 arg 为 ? GetValue (ref )。
返回 precedingArgs 和 « arg » 的列表连接 。
ArgumentList :
ArgumentList
,
...
AssignmentExpression
令 precedingArgs 为 ? ArgumentList 的 ArgumentListEvaluation 。
令 spreadRef 为 ? AssignmentExpression 的
Evaluation 。
令 iteratorRecord 为 ? GetIterator (?
GetValue (spreadRef ),
sync )。
重复,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 是 done ,返回
precedingArgs 。
将 next 附加到 precedingArgs 。
TemplateLiteral
: NoSubstitutionTemplate
令 templateLiteral 为此 TemplateLiteral 。
令 siteObj 为 GetTemplateObject (templateLiteral )。
返回 « siteObj »。
TemplateLiteral
: SubstitutionTemplate
令 templateLiteral 为此 TemplateLiteral 。
令 siteObj 为 GetTemplateObject (templateLiteral )。
令 remaining 为 ? SubstitutionTemplate 的
ArgumentListEvaluation 。
返回 « siteObj » 和 remaining 的列表连接 。
SubstitutionTemplate
:
TemplateHead
Expression
TemplateSpans
令 firstSubRef 为 ? Expression 的 Evaluation 。
令 firstSub 为 ? GetValue (firstSubRef )。
令 restSub 为 ? TemplateSpans 的 SubstitutionEvaluation 。
断言 :
restSub 是可能为空的列表 。
返回 « firstSub » 和 restSub 的列表连接 。
13.3.9 可选链
注
可选链是一个或多个属性访问和函数调用的链,其中第一个以标记 ?. 开始。
13.3.9.1 运行时语义:Evaluation
OptionalExpression
:
MemberExpression
OptionalChain
令 baseReference 为 ? MemberExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
如果 baseValue 是 undefined 或 null ,则
返回 undefined 。
返回 ? OptionalChain 以 baseValue
和 baseReference 为参数的 ChainEvaluation 。
OptionalExpression
:
CallExpression
OptionalChain
令 baseReference 为 ? CallExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
如果 baseValue 是 undefined 或 null ,则
返回 undefined 。
返回 ? OptionalChain 以 baseValue
和 baseReference 为参数的 ChainEvaluation 。
OptionalExpression
:
OptionalExpression
OptionalChain
令 baseReference 为 ? OptionalExpression 的 Evaluation 。
令 baseValue 为 ? GetValue (baseReference )。
如果 baseValue 是 undefined 或 null ,则
返回 undefined 。
返回 ? OptionalChain 以 baseValue
和 baseReference 为参数的 ChainEvaluation 。
13.3.9.2 运行时语义:ChainEvaluation
语法制导操作
ChainEvaluation 接受参数 baseValue (一个 ECMAScript 语言值 )和
baseReference (一个 ECMAScript
语言值 或引用记录 ),返回包含 ECMAScript 语言值 或引用记录 的正常完成 ,或突然完成 。它在以下产生式上分段定义:
OptionalChain :
?.
Arguments
令 thisChain 为此 OptionalChain 。
令 tailCall 为 IsInTailPosition (thisChain )。
返回 ? EvaluateCall (baseValue ,
baseReference , Arguments , tailCall )。
OptionalChain :
?.
[
Expression
]
令 strict 为此 OptionalChain 的 IsStrict 。
返回 ? EvaluatePropertyAccessWithExpressionKey (baseValue ,
Expression ,
strict )。
OptionalChain :
?.
IdentifierName
令 strict 为此 OptionalChain 的 IsStrict 。
返回 EvaluatePropertyAccessWithIdentifierKey (baseValue ,
IdentifierName ,
strict )。
OptionalChain :
?.
PrivateIdentifier
令 fieldNameString 为 PrivateIdentifier 的 StringValue 。
返回 MakePrivateReference (baseValue ,
fieldNameString )。
OptionalChain :
OptionalChain
Arguments
令 optionalChain 为 OptionalChain 。
令 newReference 为 ? optionalChain 以 baseValue 和
baseReference 为参数的 ChainEvaluation 。
令 newValue 为 ? GetValue (newReference )。
令 thisChain 为此 OptionalChain 。
令 tailCall 为 IsInTailPosition (thisChain )。
返回 ? EvaluateCall (newValue ,
newReference , Arguments , tailCall )。
OptionalChain :
OptionalChain
[
Expression
]
令 optionalChain 为 OptionalChain 。
令 newReference 为 ? optionalChain 以 baseValue 和
baseReference 为参数的 ChainEvaluation 。
令 newValue 为 ? GetValue (newReference )。
令 strict 为此 OptionalChain 的 IsStrict 。
返回 ? EvaluatePropertyAccessWithExpressionKey (newValue ,
Expression ,
strict )。
OptionalChain :
OptionalChain
.
IdentifierName
令 optionalChain 为 OptionalChain 。
令 newReference 为 ? optionalChain 以 baseValue 和
baseReference 为参数的 ChainEvaluation 。
令 newValue 为 ? GetValue (newReference )。
令 strict 为此 OptionalChain 的 IsStrict 。
返回 EvaluatePropertyAccessWithIdentifierKey (newValue ,
IdentifierName ,
strict )。
OptionalChain :
OptionalChain
.
PrivateIdentifier
令 optionalChain 为 OptionalChain 。
令 newReference 为 ? optionalChain 以 baseValue 和
baseReference 为参数的 ChainEvaluation 。
令 newValue 为 ? GetValue (newReference )。
令 fieldNameString 为 PrivateIdentifier 的 StringValue 。
返回 MakePrivateReference (newValue ,
fieldNameString )。
13.3.10 Import 调用
13.3.10.1 运行时语义:Evaluation
ImportCall :
import
(
AssignmentExpression
,opt
)
返回 ? EvaluateImportCall (AssignmentExpression )。
ImportCall :
import
(
AssignmentExpression
,
AssignmentExpression
,opt
)
返回 ? EvaluateImportCall (第一个 AssignmentExpression , 第二个
AssignmentExpression )。
13.3.10.2 EvaluateImportCall ( specifierExpression [
, optionsExpression ] )
抽象操作 EvaluateImportCall 接受参数 specifierExpression (一个 解析节点 )和可选参数
optionsExpression (一个 解析节点 ),返回包含 Promise
的正常完成 或突然完成 。当调用时执行以下步骤:
令 referrer 为 GetActiveScriptOrModule ()。
如果 referrer 是 null ,设置 referrer 为当前 Realm
记录 。
令 specifierRef 为 ? specifierExpression 的 Evaluation 。
令 specifier 为 ? GetValue (specifierRef )。
如果 optionsExpression 存在,则
令 optionsRef 为 ? optionsExpression 的 Evaluation 。
令 options 为 ? GetValue (optionsRef )。
否则,
令 options 为 undefined 。
令 promiseCapability 为 ! NewPromiseCapability (%Promise% )。
令 specifierString 为 Completion (ToString (specifier ))。
IfAbruptRejectPromise (specifierString ,
promiseCapability )。
令 attributes 为新的空列表 。
如果 options 不是 undefined ,则
如果 options 不是对象 ,则
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
新创建的 TypeError 对象 »)。
返回 promiseCapability .[[Promise]] 。
令 attributesObj 为 Completion (Get (options ,
"with" ))。
IfAbruptRejectPromise (attributesObj ,
promiseCapability )。
如果 attributesObj 不是 undefined ,则
如果 attributesObj 不是对象 ,则
执行 ! Call (promiseCapability .[[Reject]] ,
undefined , « 新创建的
TypeError 对象 »)。
返回 promiseCapability .[[Promise]] 。
令 entries 为 Completion (EnumerableOwnProperties (attributesObj ,
key+value ))。
IfAbruptRejectPromise (entries ,
promiseCapability )。
对于 entries 的每个元素 entry ,执行
令 key 为 ! Get (entry ,
"0" )。
令 value 为 ! Get (entry ,
"1" )。
如果 key 是字符串 ,则
如果 value 不是字符串 ,则
执行 ! Call (promiseCapability .[[Reject]] ,
undefined , « 新创建的
TypeError
对象 »)。
返回 promiseCapability .[[Promise]] 。
将ImportAttribute
记录 { [[Key]] : key ,
[[Value]] :
value } 附加到 attributes 。
如果 AllImportAttributesSupported (attributes )
是 false ,则
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
新创建的 TypeError 对象 »)。
返回 promiseCapability .[[Promise]] 。
按照其 [[Key]] 字段的字典序对 attributes
进行排序,将每个此类字段的值视为 UTF-16 代码单元值的序列。注:此排序仅在禁止宿主 基于属性枚举的顺序改变行为这一点上是可观察的。
令 moduleRequest 为新的ModuleRequest
记录 { [[Specifier]] :
specifierString , [[Attributes]] :
attributes }。
执行 HostLoadImportedModule (referrer ,
moduleRequest , empty ,
promiseCapability )。
返回 promiseCapability .[[Promise]] 。
13.3.10.3 ContinueDynamicImport ( promiseCapability ,
moduleCompletion )
抽象操作 ContinueDynamicImport 接受参数 promiseCapability (一个 PromiseCapability 记录 )和
moduleCompletion (包含
模块记录 的正常完成 或抛出完成 ),返回
unused 。它完成最初由 import()
调用开始的动态导入过程,适当地解决或拒绝由该调用返回的 promise。当调用时执行以下步骤:
如果 moduleCompletion 是突然完成 ,则
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
moduleCompletion .[[Value]] »)。
返回 unused 。
令 module 为 moduleCompletion .[[Value]] 。
令 loadPromise 为 module .LoadRequestedModules()。
令 rejectedClosure 为新的抽象闭包 ,参数为
(reason ),捕获 promiseCapability 并在调用时执行以下步骤:
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
reason »)。
返回 unused 。
令 onRejected 为 CreateBuiltinFunction (rejectedClosure ,
1, "" , « »)。
令 linkAndEvaluateClosure 为新的抽象闭包 ,无参数,捕获
module 、promiseCapability 和
onRejected 并在调用时执行以下步骤:
令 link 为 Completion (module .Link())。
如果 link 是突然完成 ,则
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
link .[[Value]] »)。
返回 unused 。
令 evaluatePromise 为 module .Evaluate()。
令 fulfilledClosure 为新的抽象闭包 ,无参数,捕获
module 和 promiseCapability
并在调用时执行以下步骤:
令 namespace 为 GetModuleNamespace (module )。
执行 ! Call (promiseCapability .[[Resolve]] , undefined , «
namespace »)。
返回 unused 。
令 onFulfilled 为 CreateBuiltinFunction (fulfilledClosure ,
0, "" , « »)。
执行 PerformPromiseThen (evaluatePromise ,
onFulfilled , onRejected )。
返回 unused 。
令 linkAndEvaluate 为 CreateBuiltinFunction (linkAndEvaluateClosure ,
0, "" , « »)。
执行 PerformPromiseThen (loadPromise ,
linkAndEvaluate , onRejected )。
返回 unused 。
13.3.11 标记模板
注
标记模板是一个函数调用,其中调用的参数来源于 TemplateLiteral
(13.2.8 )。实际参数包括模板对象(13.2.8.4 )和通过求值嵌入在 TemplateLiteral
中的表达式产生的值。
13.3.11.1 运行时语义:Evaluation
MemberExpression
:
MemberExpression
TemplateLiteral
令 tagRef 为 ? MemberExpression 的 Evaluation 。
令 tagFunc 为 ? GetValue (tagRef )。
令 thisCall 为此 MemberExpression 。
令 tailCall 为 IsInTailPosition (thisCall )。
返回 ? EvaluateCall (tagFunc ,
tagRef , TemplateLiteral ,
tailCall )。
CallExpression :
CallExpression
TemplateLiteral
令 tagRef 为 ? CallExpression 的 Evaluation 。
令 tagFunc 为 ? GetValue (tagRef )。
令 thisCall 为此 CallExpression 。
令 tailCall 为 IsInTailPosition (thisCall )。
返回 ? EvaluateCall (tagFunc ,
tagRef , TemplateLiteral ,
tailCall )。
13.3.12 元属性
13.3.12.1 运行时语义:Evaluation
NewTarget :
new
.
target
返回 GetNewTarget ()。
ImportMeta :
import
.
meta
令 module 为 GetActiveScriptOrModule ()。
断言 :
module 是源文本模块记录 。
令 importMeta 为 module .[[ImportMeta]] 。
如果 importMeta 是 empty ,则
设置 importMeta 为 OrdinaryObjectCreate (null )。
令 importMetaValues 为 HostGetImportMetaProperties (module )。
对于 importMetaValues 的每个记录
{ [[Key]] , [[Value]] } p ,执行
执行 ! CreateDataPropertyOrThrow (importMeta ,
p .[[Key]] , p .[[Value]] )。
执行 HostFinalizeImportMeta (importMeta ,
module )。
设置 module .[[ImportMeta]] 为
importMeta 。
返回 importMeta 。
否则,
断言 :importMeta
是对象 。
返回 importMeta 。
13.3.12.1.1 HostGetImportMetaProperties (
moduleRecord )
宿主定义的 抽象操作
HostGetImportMetaProperties 接受参数 moduleRecord (一个模块记录 ),返回包含字段 [[Key]] (一个属性键 )和 [[Value]] (一个ECMAScript
语言值 )的记录 的列表 。它允许宿主 为从
import.meta 返回的对象提供属性键 和值。
HostGetImportMetaProperties 的默认实现是返回新的空列表 。
13.3.12.1.2 HostFinalizeImportMeta ( importMeta ,
moduleRecord )
宿主定义的 抽象操作
HostFinalizeImportMeta 接受参数 importMeta (一个对象)和
moduleRecord (一个模块记录 ),返回
unused 。它允许宿主 执行任何特殊操作来准备从 import.meta 返回的对象。
大多数宿主 只需简单地定义
HostGetImportMetaProperties ,并保持
HostFinalizeImportMeta 的默认行为。然而,HostFinalizeImportMeta 为需要在对象暴露给 ECMAScript
代码之前直接操作对象的宿主 提供了"紧急出口"。
HostFinalizeImportMeta 的默认实现是返回
unused 。
13.4 更新表达式
语法
UpdateExpression [Yield,
Await] :
LeftHandSideExpression [?Yield,
?Await]
LeftHandSideExpression [?Yield,
?Await]
[no LineTerminator here]
++
LeftHandSideExpression [?Yield,
?Await]
[no LineTerminator here]
--
++
UnaryExpression [?Yield,
?Await]
--
UnaryExpression [?Yield,
?Await]
13.4.1 静态语义:早期错误
UpdateExpression :
LeftHandSideExpression
++
LeftHandSideExpression
--
UpdateExpression :
++
UnaryExpression
--
UnaryExpression
13.4.2 后缀递增运算符
13.4.2.1 运行时语义:Evaluation
UpdateExpression
:
LeftHandSideExpression
++
令 lhs 为 ? LeftHandSideExpression 的
Evaluation 。
令 oldValue 为 ? ToNumeric (?
GetValue (lhs ))。
如果 oldValue 是数字 ,则
令 newValue 为 Number::add (oldValue ,
1 𝔽 )。
否则,
断言 :oldValue 是
BigInt 。
令 newValue 为 BigInt::add (oldValue ,
1 ℤ )。
执行 ? PutValue (lhs ,
newValue )。
返回 oldValue 。
13.4.3 后缀递减运算符
13.4.3.1 运行时语义:Evaluation
UpdateExpression
:
LeftHandSideExpression
--
令 lhs 为 ? LeftHandSideExpression 的
Evaluation 。
令 oldValue 为 ? ToNumeric (?
GetValue (lhs ))。
如果 oldValue 是数字 ,则
令 newValue 为 Number::subtract (oldValue ,
1 𝔽 )。
否则,
断言 :oldValue 是
BigInt 。
令 newValue 为 BigInt::subtract (oldValue ,
1 ℤ )。
执行 ? PutValue (lhs ,
newValue )。
返回 oldValue 。
13.4.4 前缀递增运算符
13.4.4.1 运行时语义:Evaluation
UpdateExpression
:
++
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
令 oldValue 为 ? ToNumeric (?
GetValue (expr ))。
如果 oldValue 是数字 ,则
令 newValue 为 Number::add (oldValue ,
1 𝔽 )。
否则,
断言 :oldValue 是
BigInt 。
令 newValue 为 BigInt::add (oldValue ,
1 ℤ )。
执行 ? PutValue (expr ,
newValue )。
返回 newValue 。
13.4.5 前缀递减运算符
13.4.5.1 运行时语义:Evaluation
UpdateExpression
:
--
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
令 oldValue 为 ? ToNumeric (?
GetValue (expr ))。
如果 oldValue 是数字 ,则
令 newValue 为 Number::subtract (oldValue ,
1 𝔽 )。
否则,
断言 :oldValue 是
BigInt 。
令 newValue 为 BigInt::subtract (oldValue ,
1 ℤ )。
执行 ? PutValue (expr ,
newValue )。
返回 newValue 。
13.5 一元运算符
语法
UnaryExpression [Yield,
Await] :
UpdateExpression [?Yield,
?Await]
delete
UnaryExpression [?Yield,
?Await]
void
UnaryExpression [?Yield,
?Await]
typeof
UnaryExpression [?Yield,
?Await]
+
UnaryExpression [?Yield,
?Await]
-
UnaryExpression [?Yield,
?Await]
~
UnaryExpression [?Yield,
?Await]
!
UnaryExpression [?Yield,
?Await]
[+Await]
AwaitExpression [?Yield]
13.5.1 delete 运算符
13.5.1.1 静态语义:早期错误
UnaryExpression
:
delete
UnaryExpression
注
最后一条规则意味着如 delete (((foo))) 这样的表达式由于第一条规则的递归应用而产生早期错误 。
13.5.1.2 运行时语义:Evaluation
UnaryExpression
:
delete
UnaryExpression
令 ref 为 ? UnaryExpression 的 Evaluation 。
如果 ref 不是引用记录 ,返回
true 。
如果 IsUnresolvableReference (ref )
是 true ,则
断言 :ref .[[Strict]] 是 false 。
返回 true 。
如果 IsPropertyReference (ref )
是 true ,则
断言 :IsPrivateReference (ref )
是 false 。
如果 IsSuperReference (ref )
是 true ,抛出 ReferenceError
异常。
令 baseObj 为
? ToObject (ref .[[Base]] )。
如果 ref .[[ReferencedName]] 不是属性键 ,则
设置 ref .[[ReferencedName]] 为
? ToPropertyKey (ref .[[ReferencedName]] )。
令 deleteStatus 为 ? baseObj .[[Delete]] (ref .[[ReferencedName]] )。
如果 deleteStatus 是 false 并且
ref .[[Strict]] 是
true ,抛出 TypeError 异常。
返回 deleteStatus 。
否则,
令 base 为 ref .[[Base]] 。
断言 :base 是环境记录 。
返回 ? base .DeleteBinding (ref .[[ReferencedName]] )。
注 1
当 delete 运算符出现在严格模式代码 中时,如果其 UnaryExpression
是对变量、函数参数或函数名的直接引用,则抛出 SyntaxError 异常。此外,如果 delete
运算符出现在严格模式代码 中并且要删除的属性具有属性 { [[Configurable]] : false }(或者无法删除),则抛出
TypeError 异常。
注 2
可能在步骤 4.c
中创建的对象在上述抽象操作和普通对象 [[Delete]] 内部方法之外是不可访问的。实现可能选择避免实际创建该对象。
13.5.2 void 运算符
13.5.2.1 运行时语义:Evaluation
UnaryExpression
:
void
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
执行 ? GetValue (expr )。
返回 undefined 。
注
即使不使用 GetValue 的值,也必须调用它,因为它可能有可观察的副作用。
13.5.3 typeof 运算符
13.5.3.1 运行时语义:Evaluation
UnaryExpression
:
typeof
UnaryExpression
令 val 为 ? UnaryExpression 的 Evaluation 。
如果 val 是引用记录 ,则
如果 IsUnresolvableReference (val )
是 true ,返回 "undefined" 。
设置 val 为 ? GetValue (val )。
如果 val 是 undefined ,返回
"undefined" 。
如果 val 是 null ,返回 "object" 。
如果 val 是字符串 ,返回
"string" 。
如果 val 是符号 ,返回
"symbol" 。
如果 val 是布尔值 ,返回
"boolean" 。
如果 val 是数字 ,返回
"number" 。
如果 val 是
BigInt ,返回 "bigint" 。
断言 :
val 是对象 。
注:此步骤在 B.3.6.3 节中被替换。
如果 val 具有 [[Call]] 内部槽,返回
"function" 。
返回 "object" 。
13.5.4 一元 + 运算符
注
13.5.4.1 运行时语义:Evaluation
UnaryExpression
:
+
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
返回 ? ToNumber (? GetValue (expr ))。
13.5.5 一元 - 运算符
注
一元 - 运算符将其操作数转换为数值然后对其取反。对 +0 𝔽 取反产生
-0 𝔽 ,对 -0 𝔽
取反产生 +0 𝔽 。
13.5.5.1 运行时语义:Evaluation
UnaryExpression
:
-
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
令 oldValue 为 ? ToNumeric (?
GetValue (expr ))。
如果 oldValue 是数字 ,则
返回 Number::unaryMinus (oldValue )。
否则,
断言 :oldValue 是
BigInt 。
返回 BigInt::unaryMinus (oldValue )。
13.5.6 按位非运算符(~)
13.5.6.1 运行时语义:Evaluation
UnaryExpression
:
~
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
令 oldValue 为 ? ToNumeric (?
GetValue (expr ))。
如果 oldValue 是数字 ,则
返回 Number::bitwiseNOT (oldValue )。
否则,
断言 :oldValue 是
BigInt 。
返回 BigInt::bitwiseNOT (oldValue )。
13.5.7 逻辑非运算符(!)
13.5.7.1 运行时语义:Evaluation
UnaryExpression
:
!
UnaryExpression
令 expr 为 ? UnaryExpression 的 Evaluation 。
令 oldValue 为 ToBoolean (? GetValue (expr ))。
如果 oldValue 是 true ,返回 false 。
返回 true 。
13.6 幂运算符
语法
ExponentiationExpression [Yield,
Await] :
UnaryExpression [?Yield,
?Await]
UpdateExpression [?Yield,
?Await]
**
ExponentiationExpression [?Yield,
?Await]
13.6.1 运行时语义:Evaluation
ExponentiationExpression
:
UpdateExpression
**
ExponentiationExpression
返回 ? EvaluateStringOrNumericBinaryExpression (UpdateExpression ,
**, ExponentiationExpression )。
13.7 乘法运算符
语法
MultiplicativeExpression [Yield,
Await] :
ExponentiationExpression [?Yield,
?Await]
MultiplicativeExpression [?Yield,
?Await]
MultiplicativeOperator
ExponentiationExpression [?Yield,
?Await]
MultiplicativeOperator
: one of * /
%
注
* 运算符执行乘法,产生其操作数的乘积。
/ 运算符执行除法,产生其操作数的商。
% 运算符产生隐含除法中其操作数的余数。
13.7.1 运行时语义:Evaluation
MultiplicativeExpression
:
MultiplicativeExpression
MultiplicativeOperator
ExponentiationExpression
令 opText 为 MultiplicativeOperator
匹配的源文本 。
返回 ? EvaluateStringOrNumericBinaryExpression (MultiplicativeExpression ,
opText , ExponentiationExpression )。
13.8 加法运算符
语法
AdditiveExpression [Yield,
Await] :
MultiplicativeExpression [?Yield,
?Await]
AdditiveExpression [?Yield,
?Await]
+
MultiplicativeExpression [?Yield,
?Await]
AdditiveExpression [?Yield,
?Await]
-
MultiplicativeExpression [?Yield,
?Await]
13.8.1 加法运算符(+)
注
13.8.1.1 运行时语义:Evaluation
AdditiveExpression
:
AdditiveExpression
+
MultiplicativeExpression
返回 ? EvaluateStringOrNumericBinaryExpression (AdditiveExpression ,
+, MultiplicativeExpression )。
13.8.2 减法运算符(-)
注
13.8.2.1 运行时语义:Evaluation
AdditiveExpression
:
AdditiveExpression
-
MultiplicativeExpression
返回 ? EvaluateStringOrNumericBinaryExpression (AdditiveExpression ,
-, MultiplicativeExpression )。
13.9 按位移位运算符
语法
ShiftExpression [Yield,
Await] :
AdditiveExpression [?Yield,
?Await]
ShiftExpression [?Yield,
?Await]
<<
AdditiveExpression [?Yield,
?Await]
ShiftExpression [?Yield,
?Await]
>>
AdditiveExpression [?Yield,
?Await]
ShiftExpression [?Yield,
?Await]
>>>
AdditiveExpression [?Yield,
?Await]
13.9.1 左移运算符(<<)
注
对左操作数执行按位左移操作,移位量由右操作数指定。
13.9.1.1 运行时语义:Evaluation
ShiftExpression
:
ShiftExpression
<<
AdditiveExpression
返回 ? EvaluateStringOrNumericBinaryExpression (ShiftExpression ,
<<, AdditiveExpression )。
13.9.2 有符号右移运算符(>>)
注
对左操作数执行符号填充的按位右移操作,移位量由右操作数指定。
13.9.2.1 运行时语义:Evaluation
ShiftExpression
:
ShiftExpression
>>
AdditiveExpression
返回 ? EvaluateStringOrNumericBinaryExpression (ShiftExpression ,
>>, AdditiveExpression )。
13.9.3 无符号右移运算符(>>>)
注
对左操作数执行零填充的按位右移操作,移位量由右操作数指定。
13.9.3.1 运行时语义:Evaluation
ShiftExpression
:
ShiftExpression
>>>
AdditiveExpression
返回 ? EvaluateStringOrNumericBinaryExpression (ShiftExpression ,
>>>, AdditiveExpression )。
13.10 关系运算符
注 1
关系运算符的求值结果总是布尔类型,反映运算符所命名的关系是否在其两个操作数之间成立。
语法
RelationalExpression [In,
Yield, Await] :
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
<
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
>
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
<=
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
>=
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
instanceof
ShiftExpression [?Yield,
?Await]
[+In]
RelationalExpression [+In,
?Yield, ?Await]
in
ShiftExpression [?Yield,
?Await]
[+In]
PrivateIdentifier
in
ShiftExpression [?Yield,
?Await]
注 2
需要 [In] 语法参数来避免关系表达式中的 in 运算符与 for 语句中的 in
运算符混淆。
13.10.1 运行时语义:Evaluation
RelationalExpression
:
RelationalExpression
<
ShiftExpression
令 lRef 为 ? RelationalExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 r 为 ? IsLessThan (lVal , rVal ,
true )。
如果 r 是 undefined ,返回 false 。否则,返回
r 。
RelationalExpression
:
RelationalExpression
>
ShiftExpression
令 lRef 为 ? RelationalExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 r 为 ? IsLessThan (rVal , lVal ,
false )。
如果 r 是 undefined ,返回 false 。否则,返回
r 。
RelationalExpression
:
RelationalExpression
<=
ShiftExpression
令 lRef 为 ? RelationalExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 r 为 ? IsLessThan (rVal , lVal ,
false )。
如果 r 是 true 或 undefined ,返回
false 。否则,返回 true 。
RelationalExpression
:
RelationalExpression
>=
ShiftExpression
令 lRef 为 ? RelationalExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 r 为 ? IsLessThan (lVal , rVal ,
true )。
如果 r 是 true 或 undefined ,返回
false 。否则,返回 true 。
RelationalExpression
:
RelationalExpression
instanceof
ShiftExpression
令 lRef 为 ? RelationalExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
返回 ? InstanceofOperator (lVal ,
rVal )。
RelationalExpression
:
RelationalExpression
in
ShiftExpression
令 lRef 为 ? RelationalExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
如果 rVal 不是对象 ,抛出 TypeError 异常。
返回 ? HasProperty (rVal , ? ToPropertyKey (lVal ))。
RelationalExpression
:
PrivateIdentifier
in
ShiftExpression
令 privateIdentifier 为 PrivateIdentifier 的 StringValue 。
令 rRef 为 ? ShiftExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
如果 rVal 不是对象 ,抛出 TypeError 异常。
令 privateEnv 为正在运行的执行上下文 的 PrivateEnvironment。
断言 :
privateEnv 不是 null 。
令 privateName 为 ResolvePrivateIdentifier (privateEnv ,
privateIdentifier )。
如果 PrivateElementFind (rVal ,
privateName ) 不是 empty ,返回 true 。
返回 false 。
13.10.2 InstanceofOperator ( V , target )
抽象操作 InstanceofOperator 接受参数 V (ECMAScript 语言值 )和
target (ECMAScript 语言值 )并且返回包含 布尔值的正常完成 或抛出完成 。它实现用于确定
V 是否为 target 实例的通用算法,通过咨询 target 的 %Symbol.hasInstance% 方法,或如果不存在,则确定
target 的 "prototype" 属性的值是否存在于 V 的原型链中。调用时执行以下步骤:
如果 target 不是对象 ,抛出 TypeError 异常。
令 instOfHandler 为 ? GetMethod (target , %Symbol.hasInstance% )。
如果 instOfHandler 不是 undefined ,则
返回 ToBoolean (? Call (instOfHandler ,
target , « V »))。
如果 IsCallable (target ) 是
false ,抛出 TypeError 异常。
返回 ? OrdinaryHasInstance (target ,
V )。
注
步骤 4 和 5 提供与 ECMAScript
早期版本的兼容性,这些版本没有使用 %Symbol.hasInstance% 方法来定义
instanceof 运算符语义。如果对象没有定义或继承 %Symbol.hasInstance% ,它使用默认的
instanceof 语义。
13.11 相等运算符
注
相等运算符的求值结果总是布尔类型,反映运算符所命名的关系是否在其两个操作数之间成立。
语法
EqualityExpression [In, Yield,
Await] :
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
==
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
!=
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
===
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
!==
RelationalExpression [?In,
?Yield, ?Await]
13.11.1 运行时语义:Evaluation
EqualityExpression
:
EqualityExpression
==
RelationalExpression
令 lRef 为 ? EqualityExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? RelationalExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
返回 ? IsLooselyEqual (rVal ,
lVal )。
EqualityExpression
:
EqualityExpression
!=
RelationalExpression
令 lRef 为 ? EqualityExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? RelationalExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 r 为 ? IsLooselyEqual (rVal ,
lVal )。
如果 r 是 true ,返回 false 。否则,返回
true 。
EqualityExpression
:
EqualityExpression
===
RelationalExpression
令 lRef 为 ? EqualityExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? RelationalExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
返回 IsStrictlyEqual (rVal ,
lVal )。
EqualityExpression
:
EqualityExpression
!==
RelationalExpression
令 lRef 为 ? EqualityExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? RelationalExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 r 为 IsStrictlyEqual (rVal ,
lVal )。
如果 r 是 true ,返回 false 。否则,返回
true 。
注 1
根据上述相等性定义:
字符串比较可以通过以下方式强制进行:`${a}` == `${b}`。
数值比较可以通过以下方式强制进行:+a == +b。
布尔比较可以通过以下方式强制进行:!a == !b。
注 2
相等运算符维持以下不变性:
A != B 等价于 !(A == B)。
A == B 等价于 B == A,除了 A 和 B
的求值顺序。
注 3
相等运算符并不总是传递的。例如,可能有两个不同的 String 对象,每个代表相同的 String 值;每个 String 对象都会被 ==
运算符认为等于 String 值,但两个 String 对象彼此不相等。例如:
new String("a") == "a" 和 "a" == new String("a") 都是
true 。
new String("a") == new String("a") 是 false 。
注 4
字符串的比较使用简单的代码单元值序列相等性测试。没有尝试使用 Unicode 规范中定义的更复杂的、面向语义的字符或字符串相等性和排序定义。因此,根据 Unicode
标准规范相等的字符串值可能测试为不相等。实际上,此算法假设两个字符串都已经是规范化形式。
13.12 二元按位运算符
语法
BitwiseANDExpression [In,
Yield, Await] :
EqualityExpression [?In,
?Yield, ?Await]
BitwiseANDExpression [?In,
?Yield, ?Await]
&
EqualityExpression [?In,
?Yield, ?Await]
BitwiseXORExpression [In,
Yield, Await] :
BitwiseANDExpression [?In,
?Yield, ?Await]
BitwiseXORExpression [?In,
?Yield, ?Await]
^
BitwiseANDExpression [?In,
?Yield, ?Await]
BitwiseORExpression [In,
Yield, Await] :
BitwiseXORExpression [?In,
?Yield, ?Await]
BitwiseORExpression [?In,
?Yield, ?Await]
|
BitwiseXORExpression [?In,
?Yield, ?Await]
13.12.1 运行时语义:Evaluation
BitwiseANDExpression
:
BitwiseANDExpression
&
EqualityExpression
返回 ? EvaluateStringOrNumericBinaryExpression (BitwiseANDExpression ,
&, EqualityExpression )。
BitwiseXORExpression
:
BitwiseXORExpression
^
BitwiseANDExpression
返回 ? EvaluateStringOrNumericBinaryExpression (BitwiseXORExpression ,
^, BitwiseANDExpression )。
BitwiseORExpression
:
BitwiseORExpression
|
BitwiseXORExpression
返回 ? EvaluateStringOrNumericBinaryExpression (BitwiseORExpression ,
|, BitwiseXORExpression )。
13.13 二元逻辑运算符
语法
LogicalANDExpression [In,
Yield, Await] :
BitwiseORExpression [?In,
?Yield, ?Await]
LogicalANDExpression [?In,
?Yield, ?Await]
&&
BitwiseORExpression [?In,
?Yield, ?Await]
LogicalORExpression [In,
Yield, Await] :
LogicalANDExpression [?In,
?Yield, ?Await]
LogicalORExpression [?In,
?Yield, ?Await]
||
LogicalANDExpression [?In,
?Yield, ?Await]
CoalesceExpression [In, Yield,
Await] :
CoalesceExpressionHead [?In,
?Yield, ?Await]
??
BitwiseORExpression [?In,
?Yield, ?Await]
CoalesceExpressionHead [In,
Yield, Await] :
CoalesceExpression [?In,
?Yield, ?Await]
BitwiseORExpression [?In,
?Yield, ?Await]
ShortCircuitExpression [In,
Yield, Await] :
LogicalORExpression [?In,
?Yield, ?Await]
CoalesceExpression [?In,
?Yield, ?Await]
注
&& 或 || 运算符产生的值不一定是布尔类型。产生的值总是两个操作数表达式之一的值。
13.13.1 运行时语义:Evaluation
LogicalANDExpression
:
LogicalANDExpression
&&
BitwiseORExpression
令 lRef 为 ? LogicalANDExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
如果 ToBoolean (lVal ) 是
false ,返回 lVal 。
令 rRef 为 ? BitwiseORExpression 的 Evaluation 。
返回 ? GetValue (rRef )。
LogicalORExpression
:
LogicalORExpression
||
LogicalANDExpression
令 lRef 为 ? LogicalORExpression 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
如果 ToBoolean (lVal ) 是
true ,返回 lVal 。
令 rRef 为 ? LogicalANDExpression 的 Evaluation 。
返回 ? GetValue (rRef )。
CoalesceExpression
:
CoalesceExpressionHead
??
BitwiseORExpression
令 lRef 为 ? CoalesceExpressionHead 的
Evaluation 。
令 lVal 为 ? GetValue (lRef )。
如果 lVal 是 undefined 或 null ,则
令 rRef 为 ? BitwiseORExpression 的
Evaluation 。
返回 ? GetValue (rRef )。
否则,
返回 lVal 。
13.14 条件运算符 ( ? : )
语法
ConditionalExpression [In,
Yield, Await] :
ShortCircuitExpression [?In,
?Yield, ?Await]
ShortCircuitExpression [?In,
?Yield, ?Await]
?
AssignmentExpression [+In,
?Yield, ?Await]
:
AssignmentExpression [?In,
?Yield, ?Await]
注
ECMAScript 中 ConditionalExpression 的语法与 C 和 Java
中的语法略有不同,后者允许第二个子表达式是 Expression ,但限制第三个表达式必须是 ConditionalExpression 。ECMAScript
中这种差异的动机是允许赋值表达式由条件的任一分支控制,并消除作为中间表达式的逗号表达式这种令人困惑且相当无用的情况。
13.14.1 运行时语义:Evaluation
ConditionalExpression
:
ShortCircuitExpression
?
AssignmentExpression
:
AssignmentExpression
令 lRef 为 ? ShortCircuitExpression 的
Evaluation 。
令 lVal 为 ToBoolean (? GetValue (lRef ))。
如果 lVal 是 true ,则
令 trueRef 为 ? 第一个 AssignmentExpression 的
Evaluation 。
返回 ? GetValue (trueRef )。
否则,
令 falseRef 为 ? 第二个 AssignmentExpression 的
Evaluation 。
返回 ? GetValue (falseRef )。
13.15 赋值运算符
语法
AssignmentExpression [In,
Yield, Await] :
ConditionalExpression [?In,
?Yield, ?Await]
[+Yield]
YieldExpression [?In,
?Await]
ArrowFunction [?In, ?Yield,
?Await]
AsyncArrowFunction [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
=
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
AssignmentOperator
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
&&=
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
||=
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
??=
AssignmentExpression [?In,
?Yield, ?Await]
AssignmentOperator :
one of *= /= %=
+= -= <<= >>=
>>>= &= ^= |=
**=
13.15.1 静态语义:早期错误
AssignmentExpression
:
LeftHandSideExpression
=
AssignmentExpression
AssignmentExpression
:
LeftHandSideExpression
AssignmentOperator
AssignmentExpression
LeftHandSideExpression
&&=
AssignmentExpression
LeftHandSideExpression
||=
AssignmentExpression
LeftHandSideExpression
??=
AssignmentExpression
13.15.2 运行时语义:Evaluation
AssignmentExpression
:
LeftHandSideExpression
=
AssignmentExpression
如果 LeftHandSideExpression 既不是
ObjectLiteral 也不是
ArrayLiteral ,则
令 lRef 为 ? LeftHandSideExpression
的 Evaluation 。
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 是
true 且 LeftHandSideExpression
的 IsIdentifierRef
是 true ,则
令 lhs 为 LeftHandSideExpression
的 StringValue 。
令 rVal 为 ? AssignmentExpression
以参数 lhs 进行的 NamedEvaluation 。
否则,
令 rRef 为 ? AssignmentExpression
的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
执行
? PutValue (lRef ,
rVal )。
返回 rVal 。
令 assignmentPattern 为由 LeftHandSideExpression
覆盖 的 AssignmentPattern 。
令 rRef 为 ? AssignmentExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
执行 ? assignmentPattern 以参数 rVal 进行的 DestructuringAssignmentEvaluation 。
返回 rVal 。
AssignmentExpression
:
LeftHandSideExpression
AssignmentOperator
AssignmentExpression
令 lRef 为 ? LeftHandSideExpression 的
Evaluation 。
令 lVal 为
? GetValue (lRef )。
令 rRef 为 ? AssignmentExpression 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
令 assignmentOpText 为 AssignmentOperator 匹配的源代码文本 。
令 opText 为下表中与
assignmentOpText 关联的 Unicode 代码点序列:
assignmentOpText
opText
**=
**
*=
*
/=
/
%=
%
+=
+
-=
-
<<=
<<
>>=
>>
>>>=
>>>
&=
&
^=
^
|=
|
令 r 为 ? ApplyStringOrNumericBinaryOperator (lVal ,
opText , rVal )。
执行 ? PutValue (lRef , r )。
返回 r 。
AssignmentExpression
:
LeftHandSideExpression
&&=
AssignmentExpression
令 lRef 为 ? LeftHandSideExpression 的
Evaluation 。
令 lVal 为
? GetValue (lRef )。
如果 ToBoolean (lVal ) 是
false ,返回 lVal 。
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 是
true 且 LeftHandSideExpression 的
IsIdentifierRef 是
true ,则
令 lhs 为 LeftHandSideExpression
的 StringValue 。
令 rVal 为 ? AssignmentExpression 以参数
lhs 进行的 NamedEvaluation 。
否则,
令 rRef 为 ? AssignmentExpression 的
Evaluation 。
令 rVal 为 ? GetValue (rRef )。
执行 ? PutValue (lRef , rVal )。
返回 rVal 。
AssignmentExpression
:
LeftHandSideExpression
||=
AssignmentExpression
令 lRef 为 ? LeftHandSideExpression 的
Evaluation 。
令 lVal 为
? GetValue (lRef )。
如果 ToBoolean (lVal ) 是
true ,返回 lVal 。
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 是
true 且 LeftHandSideExpression 的
IsIdentifierRef 是
true ,则
令 lhs 为 LeftHandSideExpression
的 StringValue 。
令 rVal 为 ? AssignmentExpression 以参数
lhs 进行的 NamedEvaluation 。
否则,
令 rRef 为 ? AssignmentExpression 的
Evaluation 。
令 rVal 为 ? GetValue (rRef )。
执行 ? PutValue (lRef , rVal )。
返回 rVal 。
AssignmentExpression
:
LeftHandSideExpression
??=
AssignmentExpression
令 lRef 为 ? LeftHandSideExpression 的
Evaluation 。
令 lVal 为
? GetValue (lRef )。
如果 lVal 既不是 undefined 也不是 null ,
返回 lVal 。
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 是
true 且 LeftHandSideExpression 的
IsIdentifierRef 是
true ,则
令 lhs 为 LeftHandSideExpression
的 StringValue 。
令 rVal 为 ? AssignmentExpression 以参数
lhs 进行的 NamedEvaluation 。
否则,
令 rRef 为 ? AssignmentExpression 的
Evaluation 。
令 rVal 为 ? GetValue (rRef )。
执行 ? PutValue (lRef , rVal )。
返回 rVal 。
注
当此表达式出现在严格模式代码 中时,如果步骤 1.d 、
2 、
2 、
2 、
2
中的 lRef 是不可解析的引用,这是运行时错误。如果是,则抛出 ReferenceError 异常。此外,如果步骤
8 、
6 、
6 、
6
中的 lRef 引用具有属性值 {
[[Writable]] : false } 的数据属性 ,或引用具有属性值 { [[Set]] : undefined } 的访问器属性 ,或引用对象的不存在属性且该对象的 IsExtensible 谓词返回值
false ,这是运行时错误。在这些情况下会抛出 TypeError 异常。
13.15.3 ApplyStringOrNumericBinaryOperator ( lVal ,
opText , rVal )
抽象操作 ApplyStringOrNumericBinaryOperator 接受参数 lVal (一个ECMAScript 语言值 )、
opText (**、*、/、%、
+、-、<<、>>、
>>>、&、^ 或 |)和
rVal (一个ECMAScript 语言值 ),并返回包含 String、BigInt 或
Number 的正常完成 ,或抛出完成 。当调用时,它执行以下步骤:
如果 opText 是 +,则
令 lPrim 为 ? ToPrimitive (lVal )。
令 rPrim 为 ? ToPrimitive (rVal )。
如果 lPrim 是
String 或 rPrim 是
String ,则
令 lStr 为 ? ToString (lPrim )。
令 rStr 为 ? ToString (rPrim )。
返回 lStr 和 rStr 的字符串拼接 。
设置 lVal 为 lPrim 。
设置 rVal 为 rPrim 。
注:此时,这必须是数值运算。
令 lNum 为 ? ToNumeric (lVal )。
令 rNum 为 ? ToNumeric (rVal )。
如果 SameType (lNum , rNum )
是 false ,抛出 TypeError 异常。
如果 lNum 是
BigInt ,则
如果 opText 是 **,返回 ? BigInt::exponentiate (lNum ,
rNum )。
如果 opText 是 /,返回 ? BigInt::divide (lNum ,
rNum )。
如果 opText 是 %,返回 ? BigInt::remainder (lNum ,
rNum )。
如果 opText 是 >>>,返回 ? BigInt::unsignedRightShift (lNum ,
rNum )。
令 operation 为下表中与 opText 关联的抽象操作:
否则,
断言 :
lNum 是
Number 。
令 operation 为下表中与 opText 关联的抽象操作:
返回 operation (lNum , rNum )。
注 1
在步骤 1.a 和 1.b 中对 ToPrimitive 的调用中没有提供提示。除 Date
外的所有标准对象都将缺少提示处理为给定 number ;Date 将缺少提示处理为给定
string 。异质对象 可能以其他方式处理缺少提示的情况。
注 2
步骤 1.c 与 IsLessThan
算法的步骤 3 不同,使用逻辑或运算而不是逻辑与运算。
13.15.4 EvaluateStringOrNumericBinaryExpression (
leftOperand , opText , rightOperand )
抽象操作 EvaluateStringOrNumericBinaryExpression 接受参数
leftOperand (一个解析节点 )、opText (一个 Unicode 代码点序列)和
rightOperand (一个解析节点 ),并返回包含 String、BigInt 或
Number 的正常完成 ,或异常完成 。当调用时,它执行以下步骤:
令 lRef 为 ? leftOperand 的 Evaluation 。
令 lVal 为 ? GetValue (lRef )。
令 rRef 为 ? rightOperand 的 Evaluation 。
令 rVal 为 ? GetValue (rRef )。
返回 ? ApplyStringOrNumericBinaryOperator (lVal ,
opText , rVal )。
13.15.5 解构赋值
补充语法
在处理产生式实例的某些情况下
AssignmentExpression
:
LeftHandSideExpression
=
AssignmentExpression
使用以下语法来细化对 LeftHandSideExpression 的解释:
AssignmentPattern [Yield,
Await] :
ObjectAssignmentPattern [?Yield,
?Await]
ArrayAssignmentPattern [?Yield,
?Await]
ObjectAssignmentPattern [Yield,
Await] :
{
}
{
AssignmentRestProperty [?Yield,
?Await]
}
{
AssignmentPropertyList [?Yield,
?Await]
}
{
AssignmentPropertyList [?Yield,
?Await]
,
AssignmentRestProperty [?Yield,
?Await] opt
}
ArrayAssignmentPattern [Yield,
Await] :
[
Elision opt
AssignmentRestElement [?Yield,
?Await] opt
]
[
AssignmentElementList [?Yield,
?Await]
]
[
AssignmentElementList [?Yield,
?Await]
,
Elision opt
AssignmentRestElement [?Yield,
?Await] opt
]
AssignmentRestProperty [Yield,
Await] :
...
DestructuringAssignmentTarget [?Yield,
?Await]
AssignmentPropertyList [Yield,
Await] :
AssignmentProperty [?Yield,
?Await]
AssignmentPropertyList [?Yield,
?Await]
,
AssignmentProperty [?Yield,
?Await]
AssignmentElementList [Yield,
Await] :
AssignmentElisionElement [?Yield,
?Await]
AssignmentElementList [?Yield,
?Await]
,
AssignmentElisionElement [?Yield,
?Await]
AssignmentElisionElement [Yield,
Await] :
Elision opt
AssignmentElement [?Yield,
?Await]
AssignmentProperty [Yield,
Await] :
IdentifierReference [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
PropertyName [?Yield,
?Await]
:
AssignmentElement [?Yield,
?Await]
AssignmentElement [Yield,
Await] :
DestructuringAssignmentTarget [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
AssignmentRestElement [Yield,
Await] :
...
DestructuringAssignmentTarget [?Yield,
?Await]
DestructuringAssignmentTarget [Yield,
Await] :
LeftHandSideExpression [?Yield,
?Await]
13.15.5.1 静态语义:早期错误
AssignmentProperty
:
IdentifierReference
Initializer opt
AssignmentRestProperty
:
...
DestructuringAssignmentTarget
DestructuringAssignmentTarget
: LeftHandSideExpression
13.15.5.2 运行时语义:DestructuringAssignmentEvaluation
语法导向操作
DestructuringAssignmentEvaluation 接受参数
value (一个ECMAScript 语言值 ),并返回包含
unused 的正常完成 或异常完成 。
它在以下产生式上分段定义:
ObjectAssignmentPattern
:
{
}
执行 ? RequireObjectCoercible (value )。
返回 unused 。
ObjectAssignmentPattern
:
{
AssignmentPropertyList
}
{
AssignmentPropertyList
,
}
执行 ? RequireObjectCoercible (value )。
执行 ? AssignmentPropertyList 以参数
value 进行的 PropertyDestructuringAssignmentEvaluation 。
返回 unused 。
ObjectAssignmentPattern
:
{
AssignmentRestProperty
}
执行 ? RequireObjectCoercible (value )。
令 excludedNames 为一个新的空列表 。
返回 ? AssignmentRestProperty 以参数
value 和 excludedNames 进行的 RestDestructuringAssignmentEvaluation 。
ObjectAssignmentPattern
:
{
AssignmentPropertyList
,
AssignmentRestProperty
}
执行 ? RequireObjectCoercible (value )。
令 excludedNames 为 ? AssignmentPropertyList 以参数
value 进行的 PropertyDestructuringAssignmentEvaluation 。
返回 ? AssignmentRestProperty 以参数
value 和 excludedNames 进行的 RestDestructuringAssignmentEvaluation 。
ArrayAssignmentPattern
:
[
]
令 iteratorRecord 为 ? GetIterator (value ,
sync )。
返回 ? IteratorClose (iteratorRecord ,
NormalCompletion (unused ))。
ArrayAssignmentPattern
:
[
Elision
]
令 iteratorRecord 为 ? GetIterator (value ,
sync )。
令 result 为 Completion (Elision 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 iteratorRecord .[[Done]] 是
false ,返回 ? IteratorClose (iteratorRecord ,
result )。
返回 result 。
ArrayAssignmentPattern
:
[
Elision opt
AssignmentRestElement
]
令 iteratorRecord 为 ? GetIterator (value ,
sync )。
如果存在 Elision ,则
令 status 为 Completion (Elision 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 status 是异常完成 ,则
断言 :
iteratorRecord .[[Done]] 是
true 。
返回 ? status 。
令 result 为 Completion (AssignmentRestElement 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 iteratorRecord .[[Done]] 是
false ,返回 ? IteratorClose (iteratorRecord ,
result )。
返回 result 。
ArrayAssignmentPattern
:
[
AssignmentElementList
]
令 iteratorRecord 为 ? GetIterator (value ,
sync )。
令 result 为 Completion (AssignmentElementList 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 iteratorRecord .[[Done]] 是
false ,返回 ? IteratorClose (iteratorRecord ,
result )。
返回 result 。
ArrayAssignmentPattern
:
[
AssignmentElementList
,
Elision opt
AssignmentRestElement opt
]
令 iteratorRecord 为 ? GetIterator (value ,
sync )。
令 status 为 Completion (AssignmentElementList 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 status 是异常完成 ,则
如果 iteratorRecord .[[Done]] 是
false ,返回 ? IteratorClose (iteratorRecord ,
status )。
返回 ? status 。
如果存在 Elision ,则
设置 status 为 Completion (Elision 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 status 是异常完成 ,则
断言 :
iteratorRecord .[[Done]] 是
true 。
返回 ? status 。
如果存在 AssignmentRestElement ,则
设置 status 为 Completion (AssignmentRestElement
以参数 iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation )。
如果 iteratorRecord .[[Done]] 是
false ,返回 ? IteratorClose (iteratorRecord ,
status )。
返回 ? status 。
13.15.5.3 运行时语义:PropertyDestructuringAssignmentEvaluation
语法导向操作
PropertyDestructuringAssignmentEvaluation 接受参数
value (一个ECMAScript 语言值 ),并返回包含 属性键 的列表 的正常完成 或异常完成 。它收集所有解构的属性键 的列表。它在以下产生式上分段定义:
AssignmentPropertyList
:
AssignmentPropertyList
,
AssignmentProperty
令 propertyNames 为 ? AssignmentPropertyList 以参数
value 进行的 PropertyDestructuringAssignmentEvaluation 。
令 nextNames 为 ? AssignmentProperty 以参数
value 进行的 PropertyDestructuringAssignmentEvaluation 。
返回 propertyNames 和 nextNames 的列表拼接 。
AssignmentProperty
:
IdentifierReference
Initializer opt
令 P 为 IdentifierReference 的
StringValue 。
令 lRef 为 ? ResolveBinding (P )。
令 v 为 ? GetV (value , P )。
如果存在 Initializer 且
v 是 undefined ,则
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true ,则
设置 v 为 ? Initializer 以参数
P 进行的 NamedEvaluation 。
否则,
令 defaultValue 为 ? Initializer 的
Evaluation 。
设置 v 为 ? GetValue (defaultValue )。
执行 ? PutValue (lRef , v )。
返回 « P »。
AssignmentProperty
:
PropertyName
:
AssignmentElement
令 name 为 ? PropertyName 的 Evaluation 。
执行 ? AssignmentElement 以参数
value 和 name 进行的 KeyedDestructuringAssignmentEvaluation 。
返回 « name »。
13.15.5.4 运行时语义:RestDestructuringAssignmentEvaluation
语法导向操作
RestDestructuringAssignmentEvaluation 接受参数
value (一个ECMAScript 语言值 )和
excludedNames (属性键 的列表 ),并返回包含
unused 的正常完成 或异常完成 。
它在以下产生式上分段定义:
AssignmentRestProperty
:
...
DestructuringAssignmentTarget
令 lRef 为 ? DestructuringAssignmentTarget
的 Evaluation 。
令 restObj 为 OrdinaryObjectCreate (%Object.prototype% )。
执行 ? CopyDataProperties (restObj ,
value , excludedNames )。
返回 ? PutValue (lRef ,
restObj )。
13.15.5.5 运行时语义:IteratorDestructuringAssignmentEvaluation
语法导向操作
IteratorDestructuringAssignmentEvaluation 接受参数
iteratorRecord (一个迭代器记录 ),并返回包含
unused 的正常完成 或异常完成 。
它在以下产生式上分段定义:
AssignmentElementList
: AssignmentElisionElement
返回 ? AssignmentElisionElement
以参数 iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
AssignmentElementList
:
AssignmentElementList
,
AssignmentElisionElement
执行 ? AssignmentElementList 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
返回 ? AssignmentElisionElement
以参数 iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
AssignmentElisionElement
: AssignmentElement
返回 ? AssignmentElement 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
AssignmentElisionElement
:
Elision
AssignmentElement
执行 ? Elision 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
返回 ? AssignmentElement 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
Elision : ,
如果 iteratorRecord .[[Done]] 是
false ,则
执行 ? IteratorStep (iteratorRecord )。
返回 unused 。
Elision :
Elision
,
执行 ? Elision 以参数
iteratorRecord 进行的 IteratorDestructuringAssignmentEvaluation 。
如果 iteratorRecord .[[Done]] 是
false ,则
执行 ? IteratorStep (iteratorRecord )。
返回 unused 。
AssignmentElement
:
DestructuringAssignmentTarget
Initializer opt
如果 DestructuringAssignmentTarget
既不是 ObjectLiteral
也不是 ArrayLiteral ,则
令 lRef 为 ? DestructuringAssignmentTarget
的 Evaluation 。
令 value 为 undefined 。
如果 iteratorRecord .[[Done]] 是
false ,则
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 不是 done ,则
设置 value 为 next 。
如果存在 Initializer 且
value 是 undefined ,则
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true 且 DestructuringAssignmentTarget
的 IsIdentifierRef
是 true ,则
令 target 为 DestructuringAssignmentTarget
的 StringValue 。
令 v 为 ? Initializer 以参数
target 进行的 NamedEvaluation 。
否则,
令 defaultValue 为 ? Initializer 的
Evaluation 。
令 v 为 ? GetValue (defaultValue )。
否则,
令 v 为 value 。
如果 DestructuringAssignmentTarget
是 ObjectLiteral 或
ArrayLiteral ,则
令 nestedAssignmentPattern 为被 DestructuringAssignmentTarget
覆盖 的 AssignmentPattern 。
返回 ? nestedAssignmentPattern 以参数 v 进行的 DestructuringAssignmentEvaluation 。
返回 ? PutValue (lRef , v )。
注
AssignmentRestElement
:
...
DestructuringAssignmentTarget
如果 DestructuringAssignmentTarget
既不是 ObjectLiteral
也不是 ArrayLiteral ,则
令 lRef 为 ? DestructuringAssignmentTarget
的 Evaluation 。
令 A 为 ! ArrayCreate (0)。
令 n 为 0。
重复,只要 iteratorRecord .[[Done]] 是
false ,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 不是 done ,则
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )),
next )。
设置 n 为 n + 1。
如果 DestructuringAssignmentTarget
既不是 ObjectLiteral
也不是 ArrayLiteral ,则
返回 ? PutValue (lRef ,
A )。
令 nestedAssignmentPattern 为被 DestructuringAssignmentTarget
覆盖 的 AssignmentPattern 。
返回 ? nestedAssignmentPattern 以参数 A 进行的 DestructuringAssignmentEvaluation 。
13.15.5.6 运行时语义:KeyedDestructuringAssignmentEvaluation
语法导向操作
KeyedDestructuringAssignmentEvaluation 接受参数
value (一个ECMAScript 语言值 )和
propertyName (一个属性键 ),并返回包含
unused 的正常完成 或异常完成 。
它在以下产生式上分段定义:
AssignmentElement
:
DestructuringAssignmentTarget
Initializer opt
如果 DestructuringAssignmentTarget
既不是 ObjectLiteral
也不是 ArrayLiteral ,则
令 lRef 为 ? DestructuringAssignmentTarget
的 Evaluation 。
令 v 为 ? GetV (value ,
propertyName )。
如果存在 Initializer 且
v 是 undefined ,则
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true 且 DestructuringAssignmentTarget
的 IsIdentifierRef
是 true ,则
令 target 为 DestructuringAssignmentTarget
的 StringValue 。
令 rhsValue 为 ? Initializer 以参数
target 进行的 NamedEvaluation 。
否则,
令 defaultValue 为 ? Initializer 的
Evaluation 。
令 rhsValue 为 ? GetValue (defaultValue )。
否则,
令 rhsValue 为 v 。
如果 DestructuringAssignmentTarget
是 ObjectLiteral 或
ArrayLiteral ,则
令 assignmentPattern 为被 DestructuringAssignmentTarget
覆盖 的 AssignmentPattern 。
返回 ? assignmentPattern 以参数 rhsValue 进行的 DestructuringAssignmentEvaluation 。
返回 ? PutValue (lRef ,
rhsValue )。
13.16 逗号操作符 ( , )
语法
Expression [In, Yield,
Await] :
AssignmentExpression [?In,
?Yield, ?Await]
Expression [?In, ?Yield,
?Await]
,
AssignmentExpression [?In,
?Yield, ?Await]
13.16.1 运行时语义:Evaluation
Expression :
Expression
,
AssignmentExpression
令 lRef 为 ? Expression 的 Evaluation 。
执行 ? GetValue (lRef )。
令 rRef 为 ? AssignmentExpression 的 Evaluation 。
返回 ? GetValue (rRef )。
注
必须调用 GetValue ,即使其值未被使用,因为它可能具有可观察的副作用。
14 ECMAScript 语言:语句和声明
语法
Statement [Yield, Await,
Return] :
BlockStatement [?Yield, ?Await,
?Return]
VariableStatement [?Yield,
?Await]
EmptyStatement
ExpressionStatement [?Yield,
?Await]
IfStatement [?Yield, ?Await,
?Return]
BreakableStatement [?Yield,
?Await, ?Return]
ContinueStatement [?Yield,
?Await]
BreakStatement [?Yield,
?Await]
[+Return]
ReturnStatement [?Yield,
?Await]
WithStatement [?Yield, ?Await,
?Return]
LabelledStatement [?Yield,
?Await, ?Return]
ThrowStatement [?Yield,
?Await]
TryStatement [?Yield, ?Await,
?Return]
DebuggerStatement
Declaration [Yield,
Await] :
HoistableDeclaration [?Yield,
?Await, ~Default]
ClassDeclaration [?Yield, ?Await,
~Default]
LexicalDeclaration [+In,
?Yield, ?Await]
HoistableDeclaration [Yield,
Await, Default] :
FunctionDeclaration [?Yield,
?Await, ?Default]
GeneratorDeclaration [?Yield,
?Await, ?Default]
AsyncFunctionDeclaration [?Yield,
?Await, ?Default]
AsyncGeneratorDeclaration [?Yield,
?Await, ?Default]
BreakableStatement [Yield, Await,
Return] :
IterationStatement [?Yield,
?Await, ?Return]
SwitchStatement [?Yield, ?Await,
?Return]
14.1 语句语义
14.1.1 运行时语义:Evaluation
HoistableDeclaration
:
GeneratorDeclaration
AsyncFunctionDeclaration
AsyncGeneratorDeclaration
返回 empty 。
HoistableDeclaration
: FunctionDeclaration
返回 ? FunctionDeclaration 的 Evaluation 。
BreakableStatement
:
IterationStatement
SwitchStatement
令 newLabelSet 为一个新的空列表 。
返回 ? 此 BreakableStatement
以参数 newLabelSet 进行的 LabelledEvaluation 。
14.2 块
语法
BlockStatement [Yield, Await,
Return] :
Block [?Yield, ?Await,
?Return]
Block [Yield, Await,
Return] :
{
StatementList [?Yield, ?Await,
?Return] opt
}
StatementList [Yield, Await,
Return] :
StatementListItem [?Yield,
?Await, ?Return]
StatementList [?Yield, ?Await,
?Return]
StatementListItem [?Yield,
?Await, ?Return]
StatementListItem [Yield, Await,
Return] :
Statement [?Yield, ?Await,
?Return]
Declaration [?Yield,
?Await]
14.2.1 静态语义:早期错误
Block :
{
StatementList
}
14.2.2 运行时语义:Evaluation
Block :
{
}
返回 empty 。
Block :
{
StatementList
}
令 oldEnv 为运行中执行上下文 的 LexicalEnvironment。
令 blockEnv 为 NewDeclarativeEnvironment (oldEnv )。
执行 BlockDeclarationInstantiation (StatementList ,
blockEnv )。
设置运行中执行上下文 的
LexicalEnvironment 为 blockEnv 。
令 blockValue 为 Completion (StatementList 的 Evaluation )。
设置运行中执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 ? blockValue 。
注1
无论控制如何离开 Block ,LexicalEnvironment 总是恢复到其之前的状态。
StatementList :
StatementList
StatementListItem
令 sl 为 ? StatementList 的 Evaluation 。
令 s 为 Completion (StatementListItem 的 Evaluation )。
返回 ? UpdateEmpty (s , sl )。
注2
StatementList 的值是
StatementList
中最后一个产生值的项的值。例如,以下对 eval 函数的调用都返回值 1:
eval ("1;;;;;" )
eval ("1;{}" )
eval ("1;var a;" )
14.2.3 BlockDeclarationInstantiation ( code ,
env )
抽象操作 BlockDeclarationInstantiation 接受参数 code (一个解析节点 )和
env (一个声明式环境记录 ),并返回
unused 。code 是对应于块主体的解析节点 。env
是要在其中创建绑定的环境记录 。
注
当计算 Block 或 CaseBlock 时,会创建一个新的声明式环境记录 ,并且块中声明的每个块作用域变量、常量、函数或类的绑定会在环境记录 中实例化。
调用时执行以下步骤:
令 declarations 为 code 的 LexicallyScopedDeclarations 。
令 privateEnv 为运行中执行上下文 的 PrivateEnvironment。
对于 declarations 的每个元素 d ,执行
对于 d 的 BoundNames 的每个元素
dn ,执行
如果 d 的 IsConstantDeclaration
是 true ,则
执行
! env .CreateImmutableBinding(dn ,
true )。
否则,
执行
! env .CreateMutableBinding(dn ,
false )。注:此步骤在 B.3.2.6
节中被替换。
如果 d 是 FunctionDeclaration 、GeneratorDeclaration 、AsyncFunctionDeclaration
或 AsyncGeneratorDeclaration ,则
令 fn 为 d 的 BoundNames
的唯一元素。
令 fo 为 d 以参数 env 和
privateEnv 进行的 InstantiateFunctionObject 。
执行
! env .InitializeBinding(fn , fo )。
注:此步骤在 B.3.2.6
节中被替换。
返回 unused 。
14.3 声明和变量语句
14.3.1 Let 和 Const 声明
注
let 和 const 声明定义的变量作用域限定在运行中执行上下文 的
LexicalEnvironment。这些变量在其包含的环境记录 实例化时创建,但在变量的 LexicalBinding
被计算之前不能以任何方式访问。由带有 Initializer 的 LexicalBinding 定义的变量在 LexicalBinding
被计算时(而不是在变量创建时)被赋予其 Initializer 的 AssignmentExpression 的值。如果
let
声明中的 LexicalBinding
没有 Initializer ,则在
LexicalBinding
被计算时,该变量被赋值为 undefined 。
语法
LexicalDeclaration [In,
Yield, Await] :
LetOrConst
BindingList [?In, ?Yield,
?Await]
;
LetOrConst :
let
const
BindingList [In, Yield,
Await] :
LexicalBinding [?In,
?Yield, ?Await]
BindingList [?In, ?Yield,
?Await]
,
LexicalBinding [?In,
?Yield, ?Await]
LexicalBinding [In, Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await] opt
BindingPattern [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await]
14.3.1.1 静态语义:早期错误
LexicalDeclaration
:
LetOrConst
BindingList
;
LexicalBinding :
BindingIdentifier
Initializer opt
14.3.1.2 运行时语义:Evaluation
LexicalDeclaration
:
LetOrConst
BindingList
;
执行 ? BindingList 的 Evaluation 。
返回 empty 。
BindingList :
BindingList
,
LexicalBinding
执行 ? BindingList 的 Evaluation 。
返回 ? LexicalBinding 的 Evaluation 。
LexicalBinding :
BindingIdentifier
令 lhs 为 ! ResolveBinding (BindingIdentifier
的 StringValue )。
执行 ! InitializeReferencedBinding (lhs ,
undefined )。
返回 empty 。
注
静态语义 规则确保这种形式的 LexicalBinding
永远不会出现在
const 声明中。
LexicalBinding :
BindingIdentifier
Initializer
令 bindingId 为 BindingIdentifier 的 StringValue 。
令 lhs 为 ! ResolveBinding (bindingId )。
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true ,则
令 value 为 ? Initializer
以参数 bindingId 进行的 NamedEvaluation 。
否则,
令 rhs 为 ? Initializer 的 Evaluation 。
令 value 为 ? GetValue (rhs )。
执行 ! InitializeReferencedBinding (lhs ,
value )。
返回 empty 。
LexicalBinding :
BindingPattern
Initializer
令 rhs 为 ? Initializer 的 Evaluation 。
令 value 为 ? GetValue (rhs )。
令 env 为运行中执行上下文 的
LexicalEnvironment。
返回 ? BindingPattern 以参数 value
和 env 进行的 BindingInitialization 。
14.3.2 变量语句
注
var 语句声明的变量作用域限定在运行中执行上下文 的
VariableEnvironment。var 变量在其包含的环境记录 实例化时创建,并在创建时初始化为
undefined 。在任何 VariableEnvironment 的作用域内,相同的 BindingIdentifier
可以出现在多个 VariableDeclaration
中,但这些声明共同只定义一个变量。由带有 Initializer 的 VariableDeclaration
定义的变量在 VariableDeclaration
执行时(而不是在变量创建时)被赋予其 Initializer 的 AssignmentExpression 的值。
语法
VariableStatement [Yield,
Await] :
var
VariableDeclarationList [+In,
?Yield, ?Await]
;
VariableDeclarationList [In,
Yield, Await] :
VariableDeclaration [?In,
?Yield, ?Await]
VariableDeclarationList [?In,
?Yield, ?Await]
,
VariableDeclaration [?In,
?Yield, ?Await]
VariableDeclaration [In,
Yield, Await] :
BindingIdentifier [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await] opt
BindingPattern [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await]
14.3.2.1 运行时语义:Evaluation
VariableStatement
:
var
VariableDeclarationList
;
执行 ? VariableDeclarationList 的
Evaluation 。
返回 empty 。
VariableDeclarationList
:
VariableDeclarationList
,
VariableDeclaration
执行 ? VariableDeclarationList 的
Evaluation 。
返回 ? VariableDeclaration 的
Evaluation 。
VariableDeclaration
: BindingIdentifier
返回 empty 。
VariableDeclaration
:
BindingIdentifier
Initializer
令 bindingId 为 BindingIdentifier 的 StringValue 。
令 lhs 为 ? ResolveBinding (bindingId )。
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true ,则
令 value 为 ? Initializer
以参数 bindingId 进行的 NamedEvaluation 。
否则,
令 rhs 为 ? Initializer 的 Evaluation 。
令 value 为 ? GetValue (rhs )。
执行 ? PutValue (lhs ,
value )。
返回 empty 。
注
如果 VariableDeclaration 嵌套在 with
语句中,且 VariableDeclaration 中的 BindingIdentifier
与 with 语句的对象环境记录 的绑定对象的属性名 相同,则步骤 5 将把
value 赋值给该属性,而不是赋值给 Identifier 的 VariableEnvironment 绑定。
VariableDeclaration
:
BindingPattern
Initializer
令 rhs 为 ? Initializer 的 Evaluation 。
令 rVal 为 ? GetValue (rhs )。
返回 ? BindingPattern 以参数 rVal
和 undefined 进行的 BindingInitialization 。
14.3.3 解构绑定模式
语法
BindingPattern [Yield,
Await] :
ObjectBindingPattern [?Yield,
?Await]
ArrayBindingPattern [?Yield,
?Await]
ObjectBindingPattern [Yield,
Await] :
{
}
{
BindingRestProperty [?Yield,
?Await]
}
{
BindingPropertyList [?Yield,
?Await]
}
{
BindingPropertyList [?Yield,
?Await]
,
BindingRestProperty [?Yield,
?Await] opt
}
ArrayBindingPattern [Yield,
Await] :
[
Elision opt
BindingRestElement [?Yield,
?Await] opt
]
[
BindingElementList [?Yield,
?Await]
]
[
BindingElementList [?Yield,
?Await]
,
Elision opt
BindingRestElement [?Yield,
?Await] opt
]
BindingRestProperty [Yield,
Await] :
...
BindingIdentifier [?Yield,
?Await]
BindingPropertyList [Yield,
Await] :
BindingProperty [?Yield,
?Await]
BindingPropertyList [?Yield,
?Await]
,
BindingProperty [?Yield,
?Await]
BindingElementList [Yield,
Await] :
BindingElisionElement [?Yield,
?Await]
BindingElementList [?Yield,
?Await]
,
BindingElisionElement [?Yield,
?Await]
BindingElisionElement [Yield,
Await] :
Elision opt
BindingElement [?Yield,
?Await]
BindingProperty [Yield,
Await] :
SingleNameBinding [?Yield,
?Await]
PropertyName [?Yield,
?Await]
:
BindingElement [?Yield,
?Await]
BindingElement [Yield,
Await] :
SingleNameBinding [?Yield,
?Await]
BindingPattern [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
SingleNameBinding [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
BindingRestElement [Yield,
Await] :
...
BindingIdentifier [?Yield,
?Await]
...
BindingPattern [?Yield,
?Await]
14.3.3.1 运行时语义:PropertyBindingInitialization
语法制导操作
PropertyBindingInitialization 接受参数
value (一个ECMAScript 语言值 )和
environment (一个环境记录 或
undefined ),并返回包含 列表 的属性键 的正常完成或突然完成 。它收集所有已绑定属性名的列表。它在以下产生式上分段定义:
BindingPropertyList
:
BindingPropertyList
,
BindingProperty
令 boundNames 为 ? BindingPropertyList 以参数
value 和 environment 进行的 PropertyBindingInitialization 。
令 nextNames 为 ? BindingProperty 以参数
value 和 environment 进行的 PropertyBindingInitialization 。
返回 boundNames 和 nextNames 的列表连接 。
BindingProperty
: SingleNameBinding
令 name 为 SingleNameBinding 的 BoundNames 的唯一元素。
执行 ? SingleNameBinding 以参数
value 、environment 和 name 进行的 KeyedBindingInitialization 。
返回 « name »。
BindingProperty
:
PropertyName
:
BindingElement
令 P 为 ? PropertyName 的 Evaluation 。
执行 ? BindingElement 以参数
value 、environment 和 P 进行的 KeyedBindingInitialization 。
返回 « P »。
14.3.3.2 运行时语义:RestBindingInitialization
语法制导操作
RestBindingInitialization 接受参数 value
(一个ECMAScript 语言值 )、
environment (一个环境记录 或
undefined )和 excludedNames (一个列表 ,包含属性键 ),并返回包含
unused 的正常完成或突然完成 。它在以下产生式上分段定义:
BindingRestProperty
:
...
BindingIdentifier
令 lhs 为 ? ResolveBinding (BindingIdentifier 的 StringValue ,
environment )。
令 restObj 为 OrdinaryObjectCreate (%Object.prototype% )。
执行 ? CopyDataProperties (restObj ,
value ,excludedNames )。
如果 environment 是 undefined ,返回 ? PutValue (lhs ,
restObj )。
返回 ? InitializeReferencedBinding (lhs ,
restObj )。
14.3.3.3 运行时语义:KeyedBindingInitialization
语法制导操作
KeyedBindingInitialization 接受参数 value
(一个ECMAScript 语言值 )、
environment (一个环境记录 或
undefined )和 propertyName (一个属性键 ),并返回包含
unused 的正常完成或突然完成 。
注
当为 environment 传递 undefined 时,表示应该使用 PutValue
操作来分配初始化值。这是非严格函数 的形参列表的情况。在这种情况下,形参绑定会被预初始化,以处理可能存在多个同名参数的情况。
它在以下产生式上分段定义:
BindingElement :
BindingPattern
Initializer opt
令 v 为 ? GetV (value ,
propertyName )。
如果存在 Initializer 且
v 是 undefined ,则
令 defaultValue 为 ? Initializer 的 Evaluation 。
设置 v 为 ? GetValue (defaultValue )。
返回 ? BindingPattern 以参数 v 和
environment 进行的 BindingInitialization 。
SingleNameBinding
:
BindingIdentifier
Initializer opt
令 bindingId 为 BindingIdentifier 的 StringValue 。
令 lhs 为 ? ResolveBinding (bindingId ,
environment )。
令 v 为 ? GetV (value ,
propertyName )。
如果存在 Initializer 且
v 是 undefined ,则
如果 IsAnonymousFunctionDefinition (Initializer ) 是
true ,则
设置 v 为 ? Initializer 以参数
bindingId 进行的 NamedEvaluation 。
否则,
令 defaultValue 为 ? Initializer 的
Evaluation 。
设置 v 为 ? GetValue (defaultValue )。
如果 environment 是 undefined ,返回 ? PutValue (lhs ,v )。
返回 ? InitializeReferencedBinding (lhs ,
v )。
14.4 空语句
语法
EmptyStatement :
;
14.4.1 运行时语义:Evaluation
EmptyStatement :
;
返回 empty 。
14.5 表达式语句
语法
ExpressionStatement [Yield,
Await] :
[lookahead ∉ { { , function , async
[no LineTerminator here]
function , class , let
[ }]
Expression [+In, ?Yield,
?Await]
;
注
14.5.1 运行时语义:Evaluation
ExpressionStatement
:
Expression
;
令 exprRef 为 ? Expression 的 Evaluation 。
返回 ? GetValue (exprRef )。
14.6 if 语句
语法
IfStatement [Yield, Await,
Return] :
if
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
else
Statement [?Yield, ?Await,
?Return]
if
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
[lookahead ≠ else ]
注
前瞻限制 [lookahead ≠ else] 以通常的方式解决了经典的"悬空 else"问题。也就是说,当关联的
if 的选择在其他方面模糊时,else 与候选 if 中最近的(最内层的)关联。
14.6.1 静态语义:早期错误
IfStatement :
if
(
Expression
)
Statement
else
Statement
IfStatement :
if
(
Expression
)
Statement
注
只有在实现B.3.1
中指定的扩展时,才需要应用此规则。
14.6.2 运行时语义:Evaluation
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 exprRef 为 ? Expression 的 Evaluation 。
令 exprValue 为 ToBoolean (? GetValue (exprRef ))。
如果 exprValue 是 true ,则
令 stmtCompletion 为 Completion (第一个 Statement 的 Evaluation )。
否则,
令 stmtCompletion 为 Completion (第二个 Statement 的 Evaluation )。
返回 ? UpdateEmpty (stmtCompletion ,
undefined )。
IfStatement :
if
(
Expression
)
Statement
令 exprRef 为 ? Expression 的 Evaluation 。
令 exprValue 为 ToBoolean (? GetValue (exprRef ))。
如果 exprValue 是 false ,则
返回 undefined 。
否则,
令 stmtCompletion 为 Completion (Statement 的 Evaluation )。
返回 ? UpdateEmpty (stmtCompletion ,
undefined )。
14.7 迭代语句
语法
IterationStatement [Yield,
Await, Return] :
DoWhileStatement [?Yield,
?Await, ?Return]
WhileStatement [?Yield, ?Await,
?Return]
ForStatement [?Yield, ?Await,
?Return]
ForInOfStatement [?Yield,
?Await, ?Return]
14.7.1 语义
14.7.1.1 LoopContinues ( completion ,
labelSet )
抽象操作 LoopContinues 接受参数 completion (一个完成记录 )
和 labelSet (一个列表 ,包含字符串),并返回一个布尔值。调用时执行以下步骤:
如果 completion 是正常完成 ,返回
true 。
如果 completion 不是continue
完成 ,返回 false 。
如果 completion .[[Target]] 是
empty ,返回 true 。
如果 labelSet 包含 completion .[[Target]] ,返回 true 。
返回 false 。
注
14.7.1.2 运行时语义:LoopEvaluation
语法制导操作
LoopEvaluation 接受参数 labelSet (一个列表 ,包含字符串),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。它在以下产生式上分段定义:
IterationStatement
: DoWhileStatement
返回 ? DoWhileStatement 以参数
labelSet 进行的 DoWhileLoopEvaluation 。
IterationStatement
: WhileStatement
返回 ? WhileStatement 以参数
labelSet 进行的 WhileLoopEvaluation 。
IterationStatement
: ForStatement
返回 ? ForStatement 以参数 labelSet
进行的 ForLoopEvaluation 。
IterationStatement
: ForInOfStatement
返回 ? ForInOfStatement 以参数
labelSet 进行的 ForInOfLoopEvaluation 。
14.7.2 do-while 语句
语法
DoWhileStatement [Yield,
Await, Return] :
do
Statement [?Yield, ?Await,
?Return]
while
(
Expression [+In, ?Yield,
?Await]
)
;
14.7.2.1 静态语义:早期错误
DoWhileStatement
:
do
Statement
while
(
Expression
)
;
注
只有在实现B.3.1
中指定的扩展时,才需要应用此规则。
14.7.2.2 运行时语义:DoWhileLoopEvaluation
语法制导操作
DoWhileLoopEvaluation 接受参数 labelSet (一个列表 ,包含字符串),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。它在以下产生式上分段定义:
DoWhileStatement
:
do
Statement
while
(
Expression
)
;
令 V 为 undefined 。
重复,
令 stmtResult 为 Completion (Statement 的
Evaluation )。
如果 LoopContinues (stmtResult ,
labelSet ) 是 false ,返回 ? UpdateEmpty (stmtResult ,
V )。
如果 stmtResult .[[Value]] 不是
empty ,设置 V 为 stmtResult .[[Value]] 。
令 exprRef 为 ? Expression 的 Evaluation 。
令 exprValue 为 ? GetValue (exprRef )。
如果 ToBoolean (exprValue )
是 false ,返回 V 。
14.7.3 while 语句
语法
WhileStatement [Yield, Await,
Return] :
while
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
14.7.3.1 静态语义:早期错误
WhileStatement :
while
(
Expression
)
Statement
注
只有在实现B.3.1
中指定的扩展时,才需要应用此规则。
14.7.3.2 运行时语义:WhileLoopEvaluation
语法制导操作
WhileLoopEvaluation 接受参数 labelSet (一个列表 ,包含字符串),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。它在以下产生式上分段定义:
WhileStatement :
while
(
Expression
)
Statement
令 V 为 undefined 。
重复,
令 exprRef 为 ? Expression 的 Evaluation 。
令 exprValue 为 ? GetValue (exprRef )。
如果 ToBoolean (exprValue )
是 false ,返回 V 。
令 stmtResult 为 Completion (Statement 的
Evaluation )。
如果 LoopContinues (stmtResult ,
labelSet ) 是 false ,返回 ? UpdateEmpty (stmtResult ,
V )。
如果 stmtResult .[[Value]] 不是
empty ,设置 V 为 stmtResult .[[Value]] 。
14.7.4 for 语句
语法
ForStatement [Yield, Await,
Return] :
for
(
[lookahead ≠ let
[ ]
Expression [~In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
)
Statement [?Yield, ?Await,
?Return]
for
(
var
VariableDeclarationList [~In,
?Yield, ?Await]
;
Expression [+In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
)
Statement [?Yield, ?Await,
?Return]
for
(
LexicalDeclaration [~In,
?Yield, ?Await]
Expression [+In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
)
Statement [?Yield, ?Await,
?Return]
14.7.4.1 静态语义:早期错误
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
注
只有在实现B.3.1
中指定的扩展时,才需要应用此规则。
ForStatement :
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
14.7.4.2 运行时语义:ForLoopEvaluation
语法制导操作
ForLoopEvaluation 接受参数 labelSet (一个列表 ,包含字符串),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。它在以下产生式上分段定义:
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
如果第一个 Expression
存在,则
令 exprRef 为 ? 第一个 Expression 的 Evaluation 。
执行 ? GetValue (exprRef )。
如果第二个 Expression
存在,令
test 为第二个 Expression ;否则,令
test 为 empty 。
如果第三个 Expression
存在,令
increment 为第三个 Expression ;否则,令
increment 为 empty 。
返回 ? ForBodyEvaluation (test ,
increment ,Statement ,« »,
labelSet )。
ForStatement :
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
执行 ? VariableDeclarationList 的
Evaluation 。
如果第一个 Expression
存在,令
test 为第一个 Expression ;否则,令
test 为 empty 。
如果第二个 Expression
存在,令
increment 为第二个 Expression ;否则,令
increment 为 empty 。
返回 ? ForBodyEvaluation (test ,
increment ,Statement ,« »,
labelSet )。
ForStatement :
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
令 oldEnv 为运行中执行上下文 的
LexicalEnvironment。
令 loopEnv 为 NewDeclarativeEnvironment (oldEnv )。
令 isConst 为 LexicalDeclaration 的 IsConstantDeclaration 。
令 boundNames 为 LexicalDeclaration 的 BoundNames 。
对 boundNames 的每个元素 dn ,执行
如果 isConst 是 true ,则
执行
! loopEnv .CreateImmutableBinding(dn ,
true )。
否则,
执行
! loopEnv .CreateMutableBinding(dn ,
false )。
设置运行中执行上下文 的
LexicalEnvironment 为 loopEnv 。
令 forDcl 为 Completion (LexicalDeclaration 的 Evaluation )。
如果 forDcl 是突然完成 ,则
设置运行中执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 ? forDcl 。
如果 isConst 是 false ,令 perIterationLets
为 boundNames ;否则令 perIterationLets 为新的空列表 。
如果第一个 Expression
存在,令
test 为第一个 Expression ;否则,令
test 为 empty 。
如果第二个 Expression
存在,令
increment 为第二个 Expression ;否则,令
increment 为 empty 。
令 bodyResult 为 Completion (ForBodyEvaluation (test ,
increment ,Statement ,perIterationLets ,
labelSet ))。
设置运行中执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 ? bodyResult 。
14.7.4.3 ForBodyEvaluation ( test ,
increment , stmt , perIterationBindings , labelSet
)
抽象操作 ForBodyEvaluation 接受参数 test (一个 Expression 解析节点 或
empty )、increment (一个
Expression 解析节点 或
empty )、stmt (一个 Statement 解析节点 )、perIterationBindings (一个列表 ,包含字符串)和
labelSet (一个列表 ,包含字符串),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。调用时执行以下步骤:
令 V 为 undefined 。
执行 ? CreatePerIterationEnvironment (perIterationBindings )。
重复,
如果 test 不是 empty ,则
令 testRef 为 ? test 的 Evaluation 。
令 testValue 为 ? GetValue (testRef )。
如果 ToBoolean (testValue )
是 false ,返回 V 。
令 result 为 Completion (stmt
的 Evaluation )。
如果 LoopContinues (result ,
labelSet ) 是 false ,返回 ? UpdateEmpty (result ,
V )。
如果 result .[[Value]] 不是
empty ,设置 V 为 result .[[Value]] 。
执行 ? CreatePerIterationEnvironment (perIterationBindings )。
如果 increment 不是 empty ,则
令 incRef 为 ? increment 的 Evaluation 。
执行 ? GetValue (incRef )。
14.7.4.4 CreatePerIterationEnvironment (
perIterationBindings )
抽象操作 CreatePerIterationEnvironment 接受参数
perIterationBindings (一个列表 ,包含字符串),并返回包含
unused 的正常完成或throw 完成 。调用时执行以下步骤:
如果 perIterationBindings 有任何元素,则
令 lastIterationEnv 为运行中执行上下文 的
LexicalEnvironment。
令 outer 为 lastIterationEnv .[[OuterEnv]] 。
断言 :outer 不是
null 。
令 thisIterationEnv 为 NewDeclarativeEnvironment (outer )。
对 perIterationBindings 的每个元素 bn ,执行
执行
! thisIterationEnv .CreateMutableBinding(bn ,
false )。
令 lastValue 为
? lastIterationEnv .GetBindingValue(bn ,
true )。
执行
! thisIterationEnv .InitializeBinding(bn ,
lastValue )。
设置运行中执行上下文 的
LexicalEnvironment 为
thisIterationEnv 。
返回 unused 。
14.7.5 for-in、
for-of 和 for-await-of
语句
语法
ForInOfStatement [Yield,
Await, Return] :
for
(
[lookahead ≠ let
[ ]
LeftHandSideExpression [?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
var
ForBinding [?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
ForDeclaration [?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
[lookahead ∉ { let , async
of }]
LeftHandSideExpression [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
var
ForBinding [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
ForDeclaration [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
[+Await]
for
await
(
[lookahead ≠ let ]
LeftHandSideExpression [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
[+Await]
for
await
(
var
ForBinding [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
[+Await]
for
await
(
ForDeclaration [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
ForDeclaration [Yield,
Await] :
LetOrConst
ForBinding [?Yield,
?Await]
ForBinding [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
BindingPattern [?Yield,
?Await]
注
14.7.5.1 静态语义:早期错误
ForInOfStatement
:
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
var
ForBinding
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
注
只有在实现B.3.1
中指定的扩展时,才需要应用此规则。
ForInOfStatement
:
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
ForInOfStatement
:
for
(
ForDeclaration
in
Expression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
14.7.5.2 静态语义:IsDestructuring
语法制导操作
IsDestructuring 不接受参数并返回布尔值。它在以下产生式上分段定义:
MemberExpression
: PrimaryExpression
如果 PrimaryExpression 是
ObjectLiteral 或
ArrayLiteral ,
返回 true 。
返回 false 。
MemberExpression
:
MemberExpression
[
Expression
]
MemberExpression
.
IdentifierName
MemberExpression
TemplateLiteral
SuperProperty
MetaProperty
new
MemberExpression
Arguments
MemberExpression
.
PrivateIdentifier
NewExpression :
new
NewExpression
LeftHandSideExpression
:
CallExpression
OptionalExpression
返回 false 。
ForDeclaration :
LetOrConst
ForBinding
返回 ForBinding 的
IsDestructuring 。
ForBinding : BindingIdentifier
返回 false 。
ForBinding : BindingPattern
返回 true 。
注
14.7.5.3 运行时语义:ForDeclarationBindingInitialization
语法制导操作
ForDeclarationBindingInitialization 接受参数
value (一个ECMAScript 语言值 )和
environment (一个环境记录 或
undefined ),并返回包含
unused 的正常完成或突然完成 。
注
传递 undefined 作为 environment 表示应该使用 PutValue
操作来分配初始化值。这是 var 语句和某些非严格函数 的形式参数列表的情况(见10.2.11 )。在这些情况下,词法绑定被提升并在其初始化程序求值之前预初始化。
它在以下产生式上分段定义:
ForDeclaration :
LetOrConst
ForBinding
返回 ? ForBinding
以参数 value 和 environment 进行的 BindingInitialization 。
14.7.5.4 运行时语义:ForDeclarationBindingInstantiation
语法制导操作
ForDeclarationBindingInstantiation 接受参数
environment (一个声明式环境记录 )并返回
unused 。它在以下产生式上分段定义:
ForDeclaration :
LetOrConst
ForBinding
对 ForBinding 的
BoundNames 的每个元素
name ,执行
如果 LetOrConst 的 IsConstantDeclaration
是 true ,则
执行
! environment .CreateImmutableBinding(name ,
true )。
否则,
执行
! environment .CreateMutableBinding(name ,
false )。
返回 unused 。
14.7.5.5 运行时语义:ForInOfLoopEvaluation
语法制导操作
ForInOfLoopEvaluation 接受参数 labelSet (一个包含字符串的列表 ),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。它在以下产生式上分段定义:
ForInOfStatement
:
for
(
LeftHandSideExpression
in
Expression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (« », Expression ,
enumerate )。
返回 ? ForIn/OfBodyEvaluation (LeftHandSideExpression ,
Statement ,
keyResult , enumerate ,
assignment , labelSet )。
ForInOfStatement
:
for
(
var
ForBinding
in
Expression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (« », Expression ,
enumerate )。
返回 ? ForIn/OfBodyEvaluation (ForBinding , Statement ,
keyResult , enumerate ,
var-binding , labelSet )。
ForInOfStatement
:
for
(
ForDeclaration
in
Expression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (ForDeclaration 的
BoundNames ,
Expression ,
enumerate )。
返回 ? ForIn/OfBodyEvaluation (ForDeclaration ,
Statement ,
keyResult , enumerate ,
lexical-binding , labelSet )。
ForInOfStatement
:
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (« », AssignmentExpression ,
iterate )。
返回 ? ForIn/OfBodyEvaluation (LeftHandSideExpression ,
Statement ,
keyResult , iterate ,
assignment , labelSet )。
ForInOfStatement
:
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (« », AssignmentExpression ,
iterate )。
返回 ? ForIn/OfBodyEvaluation (ForBinding , Statement ,
keyResult , iterate ,
var-binding , labelSet )。
ForInOfStatement
:
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (ForDeclaration 的
BoundNames ,
AssignmentExpression ,
iterate )。
返回 ? ForIn/OfBodyEvaluation (ForDeclaration ,
Statement ,
keyResult , iterate ,
lexical-binding , labelSet )。
ForInOfStatement
:
for
await
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (« », AssignmentExpression ,
async-iterate )。
返回 ? ForIn/OfBodyEvaluation (LeftHandSideExpression ,
Statement ,
keyResult , iterate ,
assignment , labelSet ,
async )。
ForInOfStatement
:
for
await
(
var
ForBinding
of
AssignmentExpression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (« », AssignmentExpression ,
async-iterate )。
返回 ? ForIn/OfBodyEvaluation (ForBinding , Statement ,
keyResult , iterate ,
var-binding , labelSet ,
async )。
ForInOfStatement
:
for
await
(
ForDeclaration
of
AssignmentExpression
)
Statement
令 keyResult 为 ? ForIn/OfHeadEvaluation (ForDeclaration 的
BoundNames ,
AssignmentExpression ,
async-iterate )。
返回 ? ForIn/OfBodyEvaluation (ForDeclaration ,
Statement ,
keyResult , iterate ,
lexical-binding , labelSet ,
async )。
注
14.7.5.6 ForIn/OfHeadEvaluation (
uninitializedBoundNames , expr , iterationKind )
抽象操作 ForIn/OfHeadEvaluation 接受参数
uninitializedBoundNames (一个包含字符串的列表 )、
expr (一个 Expression 解析节点 或一个 AssignmentExpression 解析节点 ),以及
iterationKind (enumerate 、iterate 或
async-iterate ),并返回包含 迭代器记录 的正常完成或突然完成 。它在被调用时执行以下步骤:
令 oldEnv 为运行执行上下文 的
LexicalEnvironment。
如果 uninitializedBoundNames 不为空,则
断言 :
uninitializedBoundNames 没有重复的条目。
令 newEnv 为 NewDeclarativeEnvironment (oldEnv )。
对 uninitializedBoundNames 的每个字符串 name ,执行
执行
! newEnv .CreateMutableBinding(name ,
false )。
设置运行执行上下文 的
LexicalEnvironment 为 newEnv 。
令 exprRef 为 Completion (Evaluation of expr )。
设置运行执行上下文 的 LexicalEnvironment
为 oldEnv 。
令 exprValue 为 ? GetValue (?
exprRef )。
如果 iterationKind 是 enumerate ,则
如果 exprValue 是 undefined 或
null ,则
返回 完成记录
{ [[Type]] :
break , [[Value]] :
empty , [[Target]] :
empty }。
令 obj 为 ! ToObject (exprValue )。
令 iterator 为 EnumerateObjectProperties (obj )。
令 nextMethod 为 ! GetV (iterator ,
"next" )。
返回迭代器记录 { [[Iterator]] : iterator , [[NextMethod]] : nextMethod , [[Done]] : false }。
否则,
断言 :
iterationKind 是
iterate 或
async-iterate 。
如果 iterationKind 是 async-iterate ,令
iteratorKind 为 async 。
否则,令 iteratorKind 为 sync 。
返回 ? GetIterator (exprValue ,
iteratorKind )。
14.7.5.7 ForIn/OfBodyEvaluation ( lhs ,
stmt , iteratorRecord , iterationKind , lhsKind ,
labelSet [ , iteratorKind ] )
抽象操作 ForIn/OfBodyEvaluation 接受参数 lhs (一个解析节点 )、stmt (一个
Statement 解析节点 )、iteratorRecord (一个迭代器记录 )、iterationKind (enumerate
或
iterate )、lhsKind (assignment 、var-binding
或 lexical-binding )、labelSet (一个包含字符串的列表 )以及可选参数
iteratorKind (sync 或
async ),并返回包含 ECMAScript 语言值 的正常完成或突然完成 。它在被调用时执行以下步骤:
如果 iteratorKind 不存在,设置 iteratorKind 为
sync 。
令 oldEnv 为运行执行上下文 的
LexicalEnvironment。
令 V 为 undefined 。
令 destructuring 为 lhs 的 IsDestructuring 。
如果 destructuring 是 true 且 lhsKind 是
assignment ,则
断言 :
lhs 是一个 LeftHandSideExpression 。
令 assignmentPattern 为被 lhs 覆盖 的 AssignmentPattern 。
重复,
令 nextResult 为 ? Call (iteratorRecord .[[NextMethod]] , iteratorRecord .[[Iterator]] )。
如果 iteratorKind 是 async ,设置
nextResult 为 ? Await (nextResult )。
如果 nextResult 不是对象 ,抛出
TypeError 异常。
令 done 为 ? IteratorComplete (nextResult )。
如果 done 是 true ,返回 V 。
令 nextValue 为 ? IteratorValue (nextResult )。
如果 lhsKind 是 assignment 或
var-binding ,则
如果 destructuring 是 true ,则
如果 lhsKind 是 assignment ,
则
令 status 为 Completion (以参数
nextValue 对 assignmentPattern
进行的 DestructuringAssignmentEvaluation )。
否则,
断言 :
lhsKind 是
var-binding 。
断言 :
lhs 是一个 ForBinding 。
令 status 为 Completion (以参数
nextValue 和
undefined 对 lhs 进行的
BindingInitialization )。
否则,
令 lhsRef 为 Completion (Evaluation of
lhs )。(它可能被重复求值。)
如果 lhsRef 是突然完成 ,则
令 status 为 lhsRef 。
否则,
令 status 为 Completion (PutValue (lhsRef .[[Value]] ,
nextValue ))。
否则,
断言 :lhsKind 是
lexical-binding 。
断言 :lhs 是一个
ForDeclaration 。
令 iterationEnv 为 NewDeclarativeEnvironment (oldEnv )。
以参数 iterationEnv 对 lhs 执行 ForDeclarationBindingInstantiation 。
设置运行执行上下文 的
LexicalEnvironment 为
iterationEnv 。
如果 destructuring 是 true ,则
令 status 为 Completion (以参数
nextValue 和
iterationEnv 对 lhs 进行的 ForDeclarationBindingInitialization )。
否则,
断言 :lhs
绑定单个名称。
令 lhsName 为 lhs 的 BoundNames
的唯一元素。
令 lhsRef 为 ! ResolveBinding (lhsName )。
令 status 为 Completion (InitializeReferencedBinding (lhsRef ,
nextValue ))。
如果 status 是突然完成 ,则
设置运行执行上下文 的
LexicalEnvironment 为
oldEnv 。
如果 iteratorKind 是 async ,返回
? AsyncIteratorClose (iteratorRecord ,
status )。
如果 iterationKind 是 enumerate ,
则
返回 ? status 。
否则,
断言 :
iterationKind 是 iterate 。
返回 ? IteratorClose (iteratorRecord ,
status )。
令 result 为 Completion (Evaluation of stmt )。
设置运行执行上下文 的
LexicalEnvironment 为 oldEnv 。
如果 LoopContinues (result ,
labelSet ) 是 false ,则
如果 iterationKind 是 enumerate ,
则
返回 ? UpdateEmpty (result ,
V )。
否则,
断言 :
iterationKind 是 iterate 。
设置 status 为 Completion (UpdateEmpty (result ,
V ))。
如果 iteratorKind 是 async ,
返回 ? AsyncIteratorClose (iteratorRecord ,
status )。
返回 ? IteratorClose (iteratorRecord ,
status )。
如果 result .[[Value]] 不是
empty ,设置 V 为 result .[[Value]] 。
14.7.5.8 运行时语义:Evaluation
BindingIdentifier
:
Identifier
yield
await
令 bindingId 为 BindingIdentifier 的 StringValue 。
返回 ? ResolveBinding (bindingId )。
14.7.5.9 EnumerateObjectProperties ( O )
抽象操作 EnumerateObjectProperties 接受参数 O (一个对象),并返回一个迭代器对象 。它在被调用时执行以下步骤:
返回一个迭代器对象 ,其
next 方法遍历 O 的所有可枚举属性的字符串值键。该迭代器对象 永远不能直接被 ECMAScript
代码访问。枚举属性的机制和顺序没有指定,但必须符合下面指定的规则。
迭代器 的 throw 和
return 方法是 null 且永远不会被调用。迭代器 的 next
方法处理对象属性以确定属性键 是否应该作为迭代器 值返回。返回的属性键 不包括 Symbol
键。目标对象的属性可能在枚举期间被删除。在被迭代器 的 next
方法处理之前被删除的属性将被忽略。如果在枚举期间向目标对象添加新属性,则不保证新添加的属性会在活跃的枚举中被处理。属性名 在任何枚举中最多被迭代器 的
next 方法返回一次。
枚举目标对象的属性包括枚举其原型的属性,以及原型的原型,依此类推,递归进行;但如果原型的属性与已经被迭代器 的 next
方法处理过的属性同名,则该原型属性不会被处理。在确定原型对象的属性是否已被处理时,不考虑 [[Enumerable]]
特性的值。原型对象的可枚举属性名必须通过调用 EnumerateObjectProperties 并传递原型对象作为参数来获得。EnumerateObjectProperties
必须通过调用目标对象的 [[OwnPropertyKeys]] 内部方法来获得目标对象的自有属性键 。目标对象的属性特性必须通过调用其 [[GetOwnProperty]]
内部方法来获得。
此外,如果 O 或其原型链中的任何对象都不是代理异质对象 、TypedArray 、模块命名空间异质对象 或实现提供的异质对象 ,则迭代器 必须表现得如同由 CreateForInIterator (O )
给出的迭代器 一样,直到发生以下情况之一:
O 或其原型链中对象的 [[Prototype]] 内部槽的值发生变化,
从 O 或其原型链中的对象删除了一个属性,
向 O 的原型链中的对象添加了一个属性,或
O 或其原型链中对象的属性的 [[Enumerable]] 特性值发生变化。
注 1
ECMAScript 实现不需要直接实现14.7.5.10.2.1
中的算法。它们可以选择任何实现,只要其行为不偏离该算法,除非违反了上一段中的约束之一。
以下是符合这些规则的 ECMAScript 生成器函数的信息性定义:
function * EnumerateObjectProperties (obj) {
const visited = new Set ();
for (const key of Reflect .ownKeys (obj)) {
if (typeof key === "symbol" ) continue ;
const desc = Reflect .getOwnPropertyDescriptor (obj, key);
if (desc) {
visited.add (key);
if (desc.enumerable ) yield key;
}
}
const proto = Reflect .getPrototypeOf (obj);
if (proto === null ) return ;
for (const protoKey of EnumerateObjectProperties (proto)) {
if (!visited.has (protoKey)) yield protoKey;
}
}
注 2
选择不要求实现匹配
CreateForInIterator 的
异质对象 列表,是因为历史上实现在这些情况下的行为有所不同,而在所有其他情况下是一致的。
14.7.5.10 For-In 迭代器对象
For-In
迭代器 是表示对某个特定对象进行特定迭代的对象。For-In 迭代器对象永远不能直接被 ECMAScript 代码访问;它们只是为了说明 EnumerateObjectProperties
的行为而存在。
14.7.5.10.1 CreateForInIterator ( object )
抽象操作 CreateForInIterator 接受参数 object (一个对象),并返回一个 For-In 迭代器 。它用于创建一个 For-In 迭代器对象 ,该对象以特定顺序遍历
object 的自有和继承的可枚举字符串属性。它在被调用时执行以下步骤:
令 iterator 为 OrdinaryObjectCreate (%ForInIteratorPrototype% ,
« [[Object]] , [[ObjectWasVisited]] , [[VisitedKeys]] , [[RemainingKeys]] »)。
设置 iterator .[[Object]] 为
object 。
设置 iterator .[[ObjectWasVisited]] 为
false 。
设置 iterator .[[VisitedKeys]] 为一个新的空列表 。
设置 iterator .[[RemainingKeys]]
为一个新的空列表 。
返回 iterator 。
14.7.5.10.2 %ForInIteratorPrototype% 对象
%ForInIteratorPrototype% 对象:
14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )
令 O 为 this 值。
断言 :
O 是对象 。
断言 :
O 具有 For-In
迭代器 实例的所有内部槽(14.7.5.10.3 )。
令 object 为 O .[[Object]] 。
重复,
如果 O .[[ObjectWasVisited]] 是
false ,则
令 keys 为 ? object .[[OwnPropertyKeys]] () 。
对 keys 的每个元素 key ,执行
如果 key 是字符串 ,则
将 key 追加到 O .[[RemainingKeys]] 。
设置 O .[[ObjectWasVisited]]
为
true 。
重复,当 O .[[RemainingKeys]] 不为空时,
令 r 为 O .[[RemainingKeys]] 的第一个元素。
从 O .[[RemainingKeys]]
中移除第一个元素。
如果 O .[[VisitedKeys]]
不包含 r ,则
令 desc 为 ? object .[[GetOwnProperty]] (r )。
如果 desc 不是
undefined ,则
将 r 追加到 O .[[VisitedKeys]] 。
如果 desc .[[Enumerable]] 是
true ,返回 CreateIteratorResultObject (r ,
false )。
设置 object 为 ? object .[[GetPrototypeOf]] () 。
设置 O .[[Object]] 为
object 。
设置 O .[[ObjectWasVisited]] 为
false 。
如果 object 是 null ,返回 CreateIteratorResultObject (undefined ,
true )。
14.7.5.10.3 For-In 迭代器实例的属性
For-In 迭代器 实例是普通对象 ,它们从 %ForInIteratorPrototype%
内在对象继承属性。For-In 迭代器 实例最初使用 表 38 中列出的内部槽创建。
表 38:For-In 迭代器 实例的内部槽
内部槽
类型
描述
[[Object]]
一个对象
正在迭代其属性的对象值。
[[ObjectWasVisited]]
一个布尔值
如果迭代器 已在 [[Object]] 上调用了 [[OwnPropertyKeys]] ,则为
true ,否则为 false 。
[[VisitedKeys]]
一个包含字符串的列表
到目前为止已被此迭代器 发出的值。
[[RemainingKeys]]
一个包含字符串的列表
在迭代其原型的属性之前(如果其原型不是 null ),当前对象剩余要发出的值。
14.8 continue 语句
语法
ContinueStatement [Yield,
Await] :
continue
;
continue
[no LineTerminator
here]
LabelIdentifier [?Yield,
?Await]
;
14.8.1 静态语义:早期错误
ContinueStatement
:
continue
;
continue
LabelIdentifier
;
14.8.2 运行时语义:Evaluation
ContinueStatement
:
continue
;
返回 完成记录 { [[Type]] :
continue , [[Value]] :
empty , [[Target]] :
empty }。
ContinueStatement
:
continue
LabelIdentifier
;
令 label 为 LabelIdentifier 的 StringValue 。
返回 完成记录 { [[Type]] :
continue , [[Value]] :
empty , [[Target]] :
label }。
14.9 break 语句
语法
BreakStatement [Yield,
Await] :
break
;
break
[no LineTerminator
here]
LabelIdentifier [?Yield,
?Await]
;
14.9.1 静态语义:早期错误
BreakStatement :
break
;
14.9.2 运行时语义:Evaluation
BreakStatement :
break
;
返回 完成记录 { [[Type]] :
break , [[Value]] :
empty , [[Target]] :
empty }。
BreakStatement :
break
LabelIdentifier
;
令 label 为 LabelIdentifier 的 StringValue 。
返回 完成记录 { [[Type]] :
break , [[Value]] :
empty , [[Target]] :
label }。
14.10 return 语句
语法
ReturnStatement [Yield,
Await] :
return
;
return
[no LineTerminator
here]
Expression [+In, ?Yield,
?Await]
;
注
return 语句使函数停止执行,并且在大多数情况下将值返回给调用者。如果省略了 Expression ,则返回值是
undefined 。否则,返回值是 Expression 的值。根据周围的上下文,return
语句可能实际上不会将值返回给调用者。例如,在 try 块中,return
语句的完成记录 可能在对
finally 块进行求值期间被另一个完成记录 替换。
14.10.1 运行时语义:Evaluation
ReturnStatement :
return
;
返回 ReturnCompletion (undefined )。
ReturnStatement :
return
Expression
;
令 exprRef 为 ? Evaluation of Expression 。
令 exprValue 为 ? GetValue (exprRef )。
如果 GetGeneratorKind () 是
async ,设置 exprValue 为 ? Await (exprValue )。
返回 ReturnCompletion (exprValue )。
14.11 with 语句
注 1
不鼓励在新的 ECMAScript 代码中使用Legacy with 语句。考虑在严格模式代码 和非严格代码 中都允许的替代方案,例如解构赋值 。
语法
WithStatement [Yield, Await,
Return] :
with
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
注 2
with 语句将计算对象的对象环境记录 添加到运行执行上下文 的词法环境中。然后使用这个增强的词法环境执行语句。最后,恢复原始的词法环境。
14.11.1 静态语义:早期错误
WithStatement :
with
(
Expression
)
Statement
注
只有在实现了B.3.1
中指定的扩展时,才需要应用第二条规则。
14.11.2 运行时语义:Evaluation
WithStatement :
with
(
Expression
)
Statement
令 val 为 ? Evaluation of Expression 。
令 obj 为 ? ToObject (? GetValue (val ))。
令 oldEnv 为运行执行上下文 的 LexicalEnvironment。
令 newEnv 为 NewObjectEnvironment (obj ,
true , oldEnv )。
设置运行执行上下文 的
LexicalEnvironment 为 newEnv 。
令 C 为 Completion (Evaluation
of Statement )。
设置运行执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 ? UpdateEmpty (C ,
undefined )。
注
无论控制如何离开嵌入的 Statement ,无论是正常方式还是通过某种形式的突然完成 或异常,LexicalEnvironment
总是恢复到其原来的状态。
14.12 switch 语句
语法
SwitchStatement [Yield, Await,
Return] :
switch
(
Expression [+In, ?Yield,
?Await]
)
CaseBlock [?Yield, ?Await,
?Return]
CaseBlock [Yield, Await,
Return] :
{
CaseClauses [?Yield, ?Await,
?Return] opt
}
{
CaseClauses [?Yield, ?Await,
?Return] opt
DefaultClause [?Yield, ?Await,
?Return]
CaseClauses [?Yield, ?Await,
?Return] opt
}
CaseClauses [Yield, Await,
Return] :
CaseClause [?Yield, ?Await,
?Return]
CaseClauses [?Yield, ?Await,
?Return]
CaseClause [?Yield, ?Await,
?Return]
CaseClause [Yield, Await,
Return] :
case
Expression [+In, ?Yield,
?Await]
:
StatementList [?Yield, ?Await,
?Return] opt
DefaultClause [Yield, Await,
Return] :
default
:
StatementList [?Yield, ?Await,
?Return] opt
14.12.1 静态语义:早期错误
SwitchStatement :
switch
(
Expression
)
CaseBlock
14.12.2 运行时语义:CaseBlockEvaluation
语法制导操作
CaseBlockEvaluation 接受参数 input (一个
ECMAScript 语言值 )并
返回一个 包含 ECMAScript 语言值 的 正常完成 或 突然完成 。它按以下产生式分段定义:
CaseBlock :
{
}
返回 undefined 。
CaseBlock :
{
CaseClauses
}
令 V 为 undefined 。
令 A 为 CaseClauses 中按源文本顺序排列的 CaseClause 项的 列表 。
令 found 为 false 。
对于 A 中的每个 CaseClause
C ,执行
如果 found 是 false ,则
设置 found 为 ? CaseClauseIsSelected (C ,
input )。
如果 found 是 true ,则
令 R 为 Completion (Evaluation of C )。
如果 R .[[Value]] 不是
empty ,设置 V 为 R .[[Value]] 。
如果 R 是 突然完成 ,返回
? UpdateEmpty (R ,
V )。
返回 V 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
令 V 为 undefined 。
如果第一个 CaseClauses 存在,则
令 A 为第一个 CaseClauses 中按源文本顺序排列的 CaseClause 项的
列表 。
否则,
令 A 为一个新的空 列表 。
令 found 为 false 。
对于 A 中的每个 CaseClause
C ,执行
如果 found 是 false ,则
设置 found 为 ? CaseClauseIsSelected (C ,
input )。
如果 found 是 true ,则
令 R 为 Completion (Evaluation of C )。
如果 R .[[Value]] 不是
empty ,设置 V 为 R .[[Value]] 。
如果 R 是 突然完成 ,返回
? UpdateEmpty (R ,
V )。
令 foundInB 为 false 。
如果第二个 CaseClauses
存在,则
令 B 为第二个 CaseClauses 中按源文本顺序排列的 CaseClause 项的
列表 。
否则,
令 B 为一个新的空 列表 。
如果 found 是 false ,则
对于 B 中的每个 CaseClause
C ,执行
如果 foundInB 是 false ,则
设置 foundInB 为 ? CaseClauseIsSelected (C ,
input )。
如果 foundInB 是 true ,则
令 R 为 Completion (Evaluation of CaseClause
C )。
如果 R .[[Value]] 不是
empty ,设置 V 为
R .[[Value]] 。
如果 R 是 突然完成 ,返回
? UpdateEmpty (R ,
V )。
如果 foundInB 是 true ,返回 V 。
令 defaultR 为 Completion (Evaluation
of DefaultClause )。
如果 defaultR .[[Value]] 不是
empty ,设置 V 为 defaultR .[[Value]] 。
如果 defaultR 是 突然完成 ,返回
? UpdateEmpty (defaultR ,
V )。
注:以下是对第二个 CaseClauses
的另一次完整迭代。
对于 B 中的每个 CaseClause
C ,执行
令 R 为 Completion (Evaluation of CaseClause
C )。
如果 R .[[Value]] 不是
empty ,设置 V 为 R .[[Value]] 。
如果 R 是 突然完成 ,返回
? UpdateEmpty (R ,
V )。
返回 V 。
14.12.3 CaseClauseIsSelected ( C , input )
抽象操作 CaseClauseIsSelected 接受参数 C (一个 CaseClause 解析节点 )和 input (一个
ECMAScript 语言值 )并
返回一个 包含 Boolean 的 正常完成 或 突然完成 。它
确定 C 是否匹配 input 。调用时执行以下步骤:
断言 :
C 是产生式
CaseClause :
case
Expression
:
StatementList opt
的实例。
令 exprRef 为 ? Evaluation of
C 的 Expression 。
令 clauseSelector 为 ? GetValue (exprRef )。
返回 IsStrictlyEqual (input ,
clauseSelector )。
注
此操作不执行 C 的 StatementList (如果有)。CaseBlock 算法使用其
返回值来确定从哪个 StatementList 开始执行。
14.12.4 运行时语义:Evaluation
SwitchStatement :
switch
(
Expression
)
CaseBlock
令 exprRef 为 ? Evaluation of Expression 。
令 switchValue 为 ? GetValue (exprRef )。
令 oldEnv 为 运行执行上下文 的 LexicalEnvironment。
令 blockEnv 为 NewDeclarativeEnvironment (oldEnv )。
执行 BlockDeclarationInstantiation (CaseBlock ,
blockEnv )。
设置 运行执行上下文 的
LexicalEnvironment 为 blockEnv 。
令 R 为 Completion (CaseBlockEvaluation of CaseBlock with argument
switchValue )。
设置 运行执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 R 。
注
无论控制如何离开 SwitchStatement ,LexicalEnvironment
总是恢复到之前的状态。
CaseClause :
case
Expression
:
返回 empty 。
CaseClause :
case
Expression
:
StatementList
返回 ? Evaluation of StatementList 。
DefaultClause :
default
:
返回 empty 。
DefaultClause :
default
:
StatementList
返回 ? Evaluation of StatementList 。
14.13 标签语句
语法
LabelledStatement [Yield, Await,
Return] :
LabelIdentifier [?Yield,
?Await]
:
LabelledItem [?Yield, ?Await,
?Return]
LabelledItem [Yield, Await,
Return] :
Statement [?Yield, ?Await,
?Return]
FunctionDeclaration [?Yield,
?Await, ~Default]
注
一个 Statement
可以用标签作为前缀。标签语句只与带标签的 break
和 continue 语句结合使用。ECMAScript 没有 goto 语句。一个
Statement 可以是
LabelledStatement
的一部分,
而它本身又可以是另一个 LabelledStatement
的一部分,以此类推。以这种方式引入的标签在描述各个语句的语义时统称为"当前标签集"。
14.13.1 静态语义:早期错误
LabelledItem : FunctionDeclaration
注
14.13.2 静态语义:IsLabelledFunction ( stmt )
抽象操作 IsLabelledFunction 接受参数 stmt (一个 Statement 解析节点 )并返回一个 Boolean。调用时执行以下步骤:
如果 stmt 不是 LabelledStatement ,返回
false 。
令 item 为 stmt 的 LabelledItem 。
如果 item 是
LabelledItem
: FunctionDeclaration
,返回 true 。
令 subStmt 为 item 的 Statement 。
返回 IsLabelledFunction (subStmt )。
14.13.3 运行时语义:Evaluation
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 ? LabelledEvaluation of this LabelledStatement
with argument « »。
14.13.4 运行时语义:LabelledEvaluation
语法制导操作
LabelledEvaluation 接受参数 labelSet (一个
字符串的 列表 )并
返回一个 包含 ECMAScript 语言值 或
empty 的 正常完成 ,或
突然完成 。它按以下产生式分段定义:
BreakableStatement
: IterationStatement
令 stmtResult 为 Completion (LoopEvaluation of IterationStatement with argument
labelSet )。
如果 stmtResult 是 break
完成 ,则
如果 stmtResult .[[Target]] 是
empty ,则
如果 stmtResult .[[Value]] 是
empty ,设置 stmtResult 为 NormalCompletion (undefined )。
否则,设置 stmtResult 为 NormalCompletion (stmtResult .[[Value]] )。
返回 ? stmtResult 。
BreakableStatement
: SwitchStatement
令 stmtResult 为 Completion (Evaluation
of SwitchStatement )。
如果 stmtResult 是 break
完成 ,则
如果 stmtResult .[[Target]] 是
empty ,则
如果 stmtResult .[[Value]] 是
empty ,设置 stmtResult 为 NormalCompletion (undefined )。
否则,设置 stmtResult 为 NormalCompletion (stmtResult .[[Value]] )。
返回 ? stmtResult 。
注 1
LabelledStatement
:
LabelIdentifier
:
LabelledItem
令 label 为 LabelIdentifier 的 StringValue 。
令 newLabelSet 为
labelSet 和 « label » 的 列表连接 。
令 stmtResult 为 Completion (LabelledEvaluation of LabelledItem with argument
newLabelSet )。
如果 stmtResult 是 break
完成 且 stmtResult .[[Target]] 是
label ,则
设置 stmtResult 为 NormalCompletion (stmtResult .[[Value]] )。
返回 ? stmtResult 。
LabelledItem : FunctionDeclaration
返回 ? Evaluation of FunctionDeclaration 。
Statement :
BlockStatement
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
ThrowStatement
TryStatement
DebuggerStatement
返回 ? Evaluation of Statement 。
注 2
14.14 throw 语句
语法
ThrowStatement [Yield,
Await] :
throw
[no LineTerminator
here]
Expression [+In, ?Yield,
?Await]
;
14.14.1 运行时语义:Evaluation
ThrowStatement :
throw
Expression
;
令 exprRef 为 ? Evaluation of Expression 。
令 exprValue 为 ? GetValue (exprRef )。
返回 ThrowCompletion (exprValue )。
14.15 try 语句
语法
TryStatement [Yield, Await,
Return] :
try
Block [?Yield, ?Await,
?Return]
Catch [?Yield, ?Await,
?Return]
try
Block [?Yield, ?Await,
?Return]
Finally [?Yield, ?Await,
?Return]
try
Block [?Yield, ?Await,
?Return]
Catch [?Yield, ?Await,
?Return]
Finally [?Yield, ?Await,
?Return]
Catch [Yield,
Await,
Return] :
catch
(
CatchParameter [?Yield,
?Await]
)
Block [?Yield, ?Await,
?Return]
catch
Block [?Yield, ?Await,
?Return]
Finally [Yield, Await,
Return] :
finally
Block [?Yield, ?Await,
?Return]
CatchParameter [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
BindingPattern [?Yield,
?Await]
注
try 语句包含一个可能发生异常情况的代码块,比如运行时错误或 throw 语句。catch
子句提供异常处理代码。当 catch 子句捕获异常时,其
CatchParameter 绑定到该异常。
14.15.1 静态语义:早期错误
Catch :
catch
(
CatchParameter
)
Block
注
此产生式的替代 静态语义 在 B.3.4 中给出。
14.15.2 运行时语义:CatchClauseEvaluation
语法制导操作
CatchClauseEvaluation 接受参数 thrownValue (一个
ECMAScript 语言值 )并
返回一个 包含 ECMAScript 语言值 或
empty 的 正常完成 ,或
突然完成 。它按以下产生式分段定义:
Catch :
catch
(
CatchParameter
)
Block
令 oldEnv 为 运行执行上下文 的 LexicalEnvironment。
令 catchEnv 为 NewDeclarativeEnvironment (oldEnv )。
对于 CatchParameter 的
BoundNames 中的每个元素
argName ,执行
执行 ! catchEnv .CreateMutableBinding(argName ,
false )。
设置 运行执行上下文 的
LexicalEnvironment 为 catchEnv 。
令 status 为 Completion (BindingInitialization of CatchParameter with
arguments thrownValue and catchEnv )。
如果 status 是 突然完成 ,则
设置 运行执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 ? status 。
令 B 为 Completion (Evaluation
of Block )。
设置 运行执行上下文 的
LexicalEnvironment 为 oldEnv 。
返回 ? B 。
Catch :
catch
Block
返回 ? Evaluation of Block 。
注
无论控制如何离开 Block ,LexicalEnvironment 总是恢复到之前的状态。
14.15.3 运行时语义:Evaluation
TryStatement :
try
Block
Catch
令 B 为 Completion (Evaluation
of Block )。
如果 B 是 throw
完成 ,令 C 为 Completion (CatchClauseEvaluation of Catch with argument
B .[[Value]] )。
否则,令 C 为 B 。
返回 ? UpdateEmpty (C ,
undefined )。
TryStatement :
try
Block
Finally
令 B 为 Completion (Evaluation
of Block )。
令 F 为 Completion (Evaluation
of Finally )。
如果 F 是 正常完成 ,设置
F 为 B 。
返回 ? UpdateEmpty (F ,
undefined )。
TryStatement :
try
Block
Catch
Finally
令 B 为 Completion (Evaluation
of Block )。
如果 B 是 throw
完成 ,令 C 为 Completion (CatchClauseEvaluation of Catch with argument
B .[[Value]] )。
否则,令 C 为 B 。
令 F 为 Completion (Evaluation
of Finally )。
如果 F 是 正常完成 ,设置
F 为 C 。
返回 ? UpdateEmpty (F ,
undefined )。
14.16 debugger 语句
语法
DebuggerStatement :
debugger
;
14.16.1 运行时语义:Evaluation
注
计算 DebuggerStatement
可能允许实现在调试器下运行时触发断点。如果调试器不存在或不活跃,此语句没有可观察的效果。
DebuggerStatement
:
debugger
;
如果 实现定义的 调试设施可用且已启用,则
执行 实现定义的
调试动作。
返回一个新的 实现定义的
完成记录 。
否则,
返回 empty 。
15 ECMAScript 语言:函数和类
注
各种 ECMAScript 语言元素会导致创建 ECMAScript 函数对象 (10.2 )。这些函数的 Evaluation 从执行其
[[Call]] 内部方法开始(10.2.1 )。
15.1 参数列表
语法
UniqueFormalParameters [Yield,
Await] :
FormalParameters [?Yield,
?Await]
FormalParameters [Yield,
Await] :
[empty]
FunctionRestParameter [?Yield,
?Await]
FormalParameterList [?Yield,
?Await]
FormalParameterList [?Yield,
?Await]
,
FormalParameterList [?Yield,
?Await]
,
FunctionRestParameter [?Yield,
?Await]
FormalParameterList [Yield,
Await] :
FormalParameter [?Yield,
?Await]
FormalParameterList [?Yield,
?Await]
,
FormalParameter [?Yield,
?Await]
FunctionRestParameter [Yield,
Await] :
BindingRestElement [?Yield,
?Await]
FormalParameter [Yield,
Await] :
BindingElement [?Yield,
?Await]
15.1.1 静态语义:早期错误
UniqueFormalParameters
: FormalParameters
FormalParameters :
FormalParameterList
注
15.1.2 静态语义:ContainsExpression
语法制导操作
ContainsExpression 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
ObjectBindingPattern
:
{
}
{
BindingRestProperty
}
返回 false 。
ObjectBindingPattern
:
{
BindingPropertyList
,
BindingRestProperty
}
返回 BindingPropertyList 的 ContainsExpression 。
ArrayBindingPattern
:
[
Elision opt
]
返回 false 。
ArrayBindingPattern
:
[
Elision opt
BindingRestElement
]
返回 BindingRestElement 的 ContainsExpression 。
ArrayBindingPattern
:
[
BindingElementList
,
Elision opt
]
返回 BindingElementList 的 ContainsExpression 。
ArrayBindingPattern
:
[
BindingElementList
,
Elision opt
BindingRestElement
]
令 has 为 BindingElementList 的 ContainsExpression 。
如果 has 是 true ,返回 true 。
返回 BindingRestElement 的 ContainsExpression 。
BindingPropertyList
:
BindingPropertyList
,
BindingProperty
令 has 为 BindingPropertyList 的 ContainsExpression 。
如果 has 是 true ,返回 true 。
返回 BindingProperty
的 ContainsExpression 。
BindingElementList
:
BindingElementList
,
BindingElisionElement
令 has 为 BindingElementList 的 ContainsExpression 。
如果 has 是 true ,返回 true 。
返回 BindingElisionElement 的
ContainsExpression 。
BindingElisionElement
:
Elision opt
BindingElement
返回 BindingElement 的
ContainsExpression 。
BindingProperty :
PropertyName
:
BindingElement
令 has 为 PropertyName 的 IsComputedPropertyKey 。
如果 has 是 true ,返回 true 。
返回 BindingElement 的
ContainsExpression 。
BindingElement :
BindingPattern
Initializer
返回 true 。
SingleNameBinding
: BindingIdentifier
返回 false 。
SingleNameBinding
:
BindingIdentifier
Initializer
返回 true 。
BindingRestElement
:
...
BindingIdentifier
返回 false 。
BindingRestElement
:
...
BindingPattern
返回 BindingPattern 的
ContainsExpression 。
FormalParameters :
[empty]
返回 false 。
FormalParameters :
FormalParameterList
,
FunctionRestParameter
如果 FormalParameterList 的 ContainsExpression
是 true ,返回 true 。
返回 FunctionRestParameter 的
ContainsExpression 。
FormalParameterList
:
FormalParameterList
,
FormalParameter
如果 FormalParameterList 的 ContainsExpression
是 true ,返回 true 。
返回 FormalParameter
的 ContainsExpression 。
ArrowParameters :
BindingIdentifier
返回 false 。
ArrowParameters :
CoverParenthesizedExpressionAndArrowParameterList
令 formals 为由 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ArrowFormalParameters 。
返回 formals 的 ContainsExpression 。
AsyncArrowBindingIdentifier
: BindingIdentifier
返回 false 。
15.1.3 静态语义:IsSimpleParameterList
语法制导操作
IsSimpleParameterList 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
BindingElement :
BindingPattern
返回 false 。
BindingElement :
BindingPattern
Initializer
返回 false 。
SingleNameBinding
: BindingIdentifier
返回 true 。
SingleNameBinding
:
BindingIdentifier
Initializer
返回 false 。
FormalParameters :
[empty]
返回 true 。
FormalParameters :
FunctionRestParameter
返回 false 。
FormalParameters :
FormalParameterList
,
FunctionRestParameter
返回 false 。
FormalParameterList
:
FormalParameterList
,
FormalParameter
如果 FormalParameterList 的 IsSimpleParameterList
是 false ,返回 false 。
返回 FormalParameter
的 IsSimpleParameterList 。
FormalParameter :
BindingElement
返回 BindingElement 的
IsSimpleParameterList 。
ArrowParameters :
BindingIdentifier
返回 true 。
ArrowParameters :
CoverParenthesizedExpressionAndArrowParameterList
令 formals 为由 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ArrowFormalParameters 。
返回 formals 的 IsSimpleParameterList 。
AsyncArrowBindingIdentifier
: BindingIdentifier
返回 true 。
CoverCallExpressionAndAsyncArrowHead
:
MemberExpression
Arguments
令 head 为由 CoverCallExpressionAndAsyncArrowHead
覆盖 的 AsyncArrowHead 。
返回 head 的 IsSimpleParameterList 。
15.1.4 静态语义:HasInitializer
语法制导操作
HasInitializer 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
BindingElement :
BindingPattern
返回 false 。
BindingElement :
BindingPattern
Initializer
返回 true 。
SingleNameBinding
: BindingIdentifier
返回 false 。
SingleNameBinding
:
BindingIdentifier
Initializer
返回 true 。
FormalParameterList
:
FormalParameterList
,
FormalParameter
如果 FormalParameterList 的 HasInitializer 是
true ,返回 true 。
返回 FormalParameter
的 HasInitializer 。
15.1.5 静态语义:ExpectedArgumentCount
语法制导操作
ExpectedArgumentCount 不接受参数并返回一个非负 整数 。它按以下产生式分段定义:
FormalParameters :
[empty]
FunctionRestParameter
返回 0。
FormalParameters :
FormalParameterList
,
FunctionRestParameter
返回 FormalParameterList 的 ExpectedArgumentCount 。
注
FormalParameterList 的
ExpectedArgumentCount 是在剩余参数或第一个具有初始化器的 FormalParameter 左侧的 FormalParameters
的数量。没有初始化器的 FormalParameter
可以出现在第一个有初始化器的参数之后,但这样的参数被认为是可选的,其默认值为 undefined 。
FormalParameterList
: FormalParameter
如果 FormalParameter
的 HasInitializer 是
true ,返回 0。
返回 1。
FormalParameterList
:
FormalParameterList
,
FormalParameter
令 count 为 FormalParameterList 的 ExpectedArgumentCount 。
如果 FormalParameterList 的 HasInitializer 是
true 或 FormalParameter 的 HasInitializer 是
true ,返回 count 。
返回 count + 1。
ArrowParameters :
BindingIdentifier
返回 1。
ArrowParameters :
CoverParenthesizedExpressionAndArrowParameterList
令 formals 为由 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ArrowFormalParameters 。
返回 formals 的 ExpectedArgumentCount 。
PropertySetParameterList
: FormalParameter
如果 FormalParameter
的 HasInitializer 是
true ,返回 0。
返回 1。
AsyncArrowBindingIdentifier
: BindingIdentifier
返回 1。
15.2 函数定义
语法
FunctionDeclaration [Yield,
Await, Default] :
function
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
[+Default]
function
(
FormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
FunctionExpression :
function
BindingIdentifier [~Yield,
~Await] opt
(
FormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
FunctionBody [Yield,
Await] :
FunctionStatementList [?Yield,
?Await]
FunctionStatementList [Yield,
Await] :
StatementList [?Yield, ?Await,
+Return] opt
15.2.1 静态语义:早期错误
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
function
(
FormalParameters
)
{
FunctionBody
}
FunctionExpression
:
function
BindingIdentifier opt
(
FormalParameters
)
{
FunctionBody
}
注
FunctionBody 的
LexicallyDeclaredNames
不包括使用 var 或 function 声明绑定的标识符。
FunctionBody : FunctionStatementList
15.2.2 静态语义:FunctionBodyContainsUseStrict
语法制导操作
FunctionBodyContainsUseStrict 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
FunctionBody : FunctionStatementList
如果 FunctionBody 的
指令序言 包含一个 Use
Strict 指令 ,返回 true ;否则,返回
false 。
15.2.3 运行时语义:EvaluateFunctionBody
语法制导操作
EvaluateFunctionBody 接受参数 functionObject (一个 ECMAScript 函数对象 )和
argumentsList (一个 ECMAScript 语言值 的 List )并返回一个 return completion 或
throw
completion 。它按以下产生式分段定义:
FunctionBody : FunctionStatementList
执行 ? FunctionDeclarationInstantiation (functionObject ,
argumentsList )。
执行 ? Evaluation of FunctionStatementList 。
注:如果前面的步骤产生了一个 normal
completion ,那么求值通过继续执行到 FunctionStatementList 的末尾而结束。
返回 ReturnCompletion (undefined )。
15.2.4 运行时语义:InstantiateOrdinaryFunctionObject
语法制导操作
InstantiateOrdinaryFunctionObject 接受参数 env (一个 Environment Record )和
privateEnv (一个 PrivateEnvironment Record 或
null )并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
令 name 为 BindingIdentifier 的 StringValue 。
令 sourceText 为 FunctionDeclaration 匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , FormalParameters , FunctionBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
name )。
执行 MakeConstructor (F )。
返回 F 。
FunctionDeclaration
:
function
(
FormalParameters
)
{
FunctionBody
}
令 sourceText 为 FunctionDeclaration 匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , FormalParameters , FunctionBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
"default" )。
执行 MakeConstructor (F )。
返回 F 。
注
匿名 FunctionDeclaration 只能作为
export default 声明的一部分出现,因此其函数代码总是 严格模式代码 。
15.2.5 运行时语义:InstantiateOrdinaryFunctionExpression
语法制导操作
InstantiateOrdinaryFunctionExpression 接受可选参数 name (一个 属性键 或 私有名称 )并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
FunctionExpression
:
function
(
FormalParameters
)
{
FunctionBody
}
如果不存在 name ,设置 name 为 "" 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 FunctionExpression 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , FormalParameters , FunctionBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
执行 MakeConstructor (closure )。
返回 closure 。
FunctionExpression
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
断言 :name 不存在。
设置 name 为 BindingIdentifier 的 StringValue 。
令 outerEnv 为 运行执行上下文 的 LexicalEnvironment。
令 funcEnv 为 NewDeclarativeEnvironment (outerEnv )。
执行 ! funcEnv .CreateImmutableBinding(name ,
false )。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 FunctionExpression 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , FormalParameters , FunctionBody ,
non-lexical-this , funcEnv , privateEnv )。
执行 SetFunctionName (closure ,
name )。
执行 MakeConstructor (closure )。
执行 ! funcEnv .InitializeBinding(name ,
closure )。
返回 closure 。
注
15.2.6 运行时语义:Evaluation
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
返回 empty 。
注 1
FunctionDeclaration
:
function
(
FormalParameters
)
{
FunctionBody
}
返回 empty 。
FunctionExpression
:
function
BindingIdentifier opt
(
FormalParameters
)
{
FunctionBody
}
返回 FunctionExpression 的 InstantiateOrdinaryFunctionExpression 。
注 2
对于使用 FunctionDeclaration 或 FunctionExpression
定义的每个函数,都会自动创建一个 "prototype" 属性,以允许该函数被用作 构造函数 。
FunctionStatementList
: [empty]
返回 undefined 。
15.3 箭头函数定义
语法
ArrowFunction [In, Yield,
Await] :
ArrowParameters [?Yield,
?Await]
[no LineTerminator here]
=>
ConciseBody [?In]
ArrowParameters [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
ConciseBody [In]
:
[lookahead ≠ { ]
ExpressionBody [?In,
~Await]
{
FunctionBody [~Yield,
~Await]
}
ExpressionBody [In,
Await] :
AssignmentExpression [?In,
~Yield, ?Await]
补充语法
当处理产生式的实例
ArrowParameters [Yield,
Await] : CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
时,CoverParenthesizedExpressionAndArrowParameterList
的解释使用以下语法进行细化:
ArrowFormalParameters [Yield,
Await] :
(
UniqueFormalParameters [?Yield,
?Await]
)
15.3.1 静态语义:早期错误
ArrowFunction :
ArrowParameters
=>
ConciseBody
ArrowParameters :
CoverParenthesizedExpressionAndArrowParameterList
15.3.2 静态语义:ConciseBodyContainsUseStrict
语法制导操作
ConciseBodyContainsUseStrict 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
ConciseBody : ExpressionBody
返回 false 。
ConciseBody :
{
FunctionBody
}
返回 FunctionBody 的
FunctionBodyContainsUseStrict 。
15.3.3 运行时语义:EvaluateConciseBody
语法制导操作
EvaluateConciseBody 接受参数 functionObject (一个 ECMAScript 函数对象 )和
argumentsList (一个 ECMAScript 语言值 的 List )并返回一个 return completion 或
throw
completion 。它按以下产生式分段定义:
ConciseBody : ExpressionBody
执行 ? FunctionDeclarationInstantiation (functionObject ,
argumentsList )。
返回 ? Evaluation of ExpressionBody 。
15.3.4 运行时语义:InstantiateArrowFunctionExpression
语法制导操作
InstantiateArrowFunctionExpression 接受可选参数 name (一个 属性键 或 私有名称 )并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
ArrowFunction :
ArrowParameters
=>
ConciseBody
如果不存在 name ,设置 name 为 "" 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 ArrowFunction 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , ArrowParameters , ConciseBody ,
lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
返回 closure 。
注
ArrowFunction 不为
arguments、super、this 或 new.target
定义局部绑定。ArrowFunction
内对 arguments、super、this 或 new.target
的任何引用都必须解析为词法封闭环境中的绑定。通常这会是紧邻封闭函数的函数环境。尽管 ArrowFunction 可能包含对 super
的引用,但在步骤 5 中创建的
函数对象 不会通过执行 MakeMethod 而成为方法。引用
super 的 ArrowFunction 总是包含在非 ArrowFunction 中,实现
super 所需的状态可以通过被 ArrowFunction 的 函数对象 捕获的 env 访问。
15.3.5 运行时语义:Evaluation
ArrowFunction :
ArrowParameters
=>
ConciseBody
返回 ArrowFunction 的
InstantiateArrowFunctionExpression 。
ExpressionBody :
AssignmentExpression
令 exprRef 为 ? Evaluation of AssignmentExpression 。
令 exprValue 为 ? GetValue (exprRef )。
返回 ReturnCompletion (exprValue )。
15.4 方法定义
语法
MethodDefinition [Yield,
Await] :
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
GeneratorMethod [?Yield,
?Await]
AsyncMethod [?Yield,
?Await]
AsyncGeneratorMethod [?Yield,
?Await]
get
ClassElementName [?Yield,
?Await]
(
)
{
FunctionBody [~Yield,
~Await]
}
set
ClassElementName [?Yield,
?Await]
(
PropertySetParameterList
)
{
FunctionBody [~Yield,
~Await]
}
PropertySetParameterList
:
FormalParameter [~Yield,
~Await]
15.4.1 静态语义:早期错误
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
MethodDefinition :
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
15.4.2 静态语义:HasDirectSuper
语法制导操作
HasDirectSuper 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
如果 UniqueFormalParameters
Contains SuperCall 是
true ,返回 true 。
返回 FunctionBody
Contains SuperCall 。
MethodDefinition :
get
ClassElementName
(
)
{
FunctionBody
}
返回 FunctionBody
Contains SuperCall 。
MethodDefinition :
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
如果 PropertySetParameterList
Contains SuperCall 是
true ,返回 true 。
返回 FunctionBody
Contains SuperCall 。
GeneratorMethod :
*
ClassElementName
(
UniqueFormalParameters
)
{
GeneratorBody
}
如果 UniqueFormalParameters
Contains SuperCall 是
true ,返回 true 。
返回 GeneratorBody
Contains SuperCall 。
AsyncGeneratorMethod
:
async
*
ClassElementName
(
UniqueFormalParameters
)
{
AsyncGeneratorBody
}
如果 UniqueFormalParameters
Contains SuperCall 是
true ,返回 true 。
返回 AsyncGeneratorBody Contains SuperCall 。
AsyncMethod :
async
ClassElementName
(
UniqueFormalParameters
)
{
AsyncFunctionBody
}
如果 UniqueFormalParameters
Contains SuperCall 是
true ,返回 true 。
返回 AsyncFunctionBody Contains SuperCall 。
15.4.3 静态语义:SpecialMethod
语法制导操作
SpecialMethod 不接受参数并返回一个 Boolean。它按以下产生式分段定义:
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
返回 false 。
MethodDefinition :
GeneratorMethod
AsyncMethod
AsyncGeneratorMethod
get
ClassElementName
(
)
{
FunctionBody
}
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
返回 true 。
15.4.4 运行时语义:DefineMethod
语法制导操作
DefineMethod 接受参数 object (一个 Object)和可选参数 functionPrototype (一个 Object)并返回
包含 一个 Record (字段为 [[Key]] (一个 属性键 )和 [[Closure]] (一个
ECMAScript 函数对象 ))的 normal completion 或
abrupt
completion 。它按以下产生式分段定义:
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
令 propKey 为 ? Evaluation of ClassElementName 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
如果存在 functionPrototype ,那么
令 prototype 为 functionPrototype 。
否则,
令 prototype 为 %Function.prototype% 。
令 sourceText 为 MethodDefinition 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (prototype ,
sourceText , UniqueFormalParameters , FunctionBody ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (closure ,
object )。
返回 Record { [[Key]] : propKey , [[Closure]] : closure }。
15.4.5 运行时语义:MethodDefinitionEvaluation
语法制导操作
MethodDefinitionEvaluation 接受参数 object (一个 Object)和 enumerable (一个
Boolean)并返回 包含 PrivateElement 或
unused 的 normal
completion ,或 abrupt
completion 。它按以下产生式分段定义:
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
令 methodDef 为 MethodDefinition 以参数
object 的 ? DefineMethod 。
执行 SetFunctionName (methodDef .[[Closure]] , methodDef .[[Key]] )。
返回 ? DefineMethodProperty (object ,
methodDef .[[Key]] , methodDef .[[Closure]] , enumerable )。
MethodDefinition :
get
ClassElementName
(
)
{
FunctionBody
}
令 propKey 为 ? Evaluation of ClassElementName 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 MethodDefinition 匹配的源文本 。
令 formalParameterList 为产生式
FormalParameters
: [empty]
的实例。
令 closure 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , formalParameterList , FunctionBody ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (closure ,
object )。
执行 SetFunctionName (closure ,
propKey , "get" )。
如果 propKey 是 私有名称 ,那么
返回 PrivateElement
{ [[Key]] : propKey , [[Kind]] : accessor , [[Get]] : closure , [[Set]] : undefined }。
否则,
令 desc 为 PropertyDescriptor { [[Get]] :
closure , [[Enumerable]] :
enumerable , [[Configurable]] :
true }。
执行 ? DefinePropertyOrThrow (object ,
propKey , desc )。
返回 unused 。
MethodDefinition :
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
令 propKey 为 ? Evaluation of ClassElementName 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 MethodDefinition 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , PropertySetParameterList ,
FunctionBody ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (closure ,
object )。
执行 SetFunctionName (closure ,
propKey , "set" )。
如果 propKey 是 私有名称 ,那么
返回 PrivateElement
{ [[Key]] : propKey , [[Kind]] : accessor , [[Get]] : undefined , [[Set]] : closure }。
否则,
令 desc 为 PropertyDescriptor { [[Set]] :
closure , [[Enumerable]] :
enumerable , [[Configurable]] :
true }。
执行 ? DefinePropertyOrThrow (object ,
propKey , desc )。
返回 unused 。
GeneratorMethod :
*
ClassElementName
(
UniqueFormalParameters
)
{
GeneratorBody
}
令 propKey 为 ? Evaluation of ClassElementName 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 GeneratorMethod 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%GeneratorFunction.prototype% ,
sourceText , UniqueFormalParameters , GeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (closure ,
object )。
执行 SetFunctionName (closure ,
propKey )。
令 prototype 为 OrdinaryObjectCreate (%GeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (closure ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 ? DefineMethodProperty (object ,
propKey , closure , enumerable )。
AsyncGeneratorMethod
:
async
*
ClassElementName
(
UniqueFormalParameters
)
{
AsyncGeneratorBody
}
令 propKey 为 ? Evaluation of ClassElementName 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 AsyncGeneratorMethod 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%AsyncGeneratorFunction.prototype% ,
sourceText , UniqueFormalParameters , AsyncGeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (closure ,
object )。
执行 SetFunctionName (closure ,
propKey )。
令 prototype 为 OrdinaryObjectCreate (%AsyncGeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (closure ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 ? DefineMethodProperty (object ,
propKey , closure , enumerable )。
AsyncMethod :
async
ClassElementName
(
UniqueFormalParameters
)
{
AsyncFunctionBody
}
令 propKey 为 ? Evaluation of ClassElementName 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 AsyncMethod 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , UniqueFormalParameters , AsyncFunctionBody ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (closure ,
object )。
执行 SetFunctionName (closure ,
propKey )。
返回 ? DefineMethodProperty (object ,
propKey , closure , enumerable )。
15.5 生成器函数定义
语法
GeneratorDeclaration [Yield,
Await, Default] :
function
*
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
[+Default]
function
*
(
FormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
GeneratorExpression
:
function
*
BindingIdentifier [+Yield,
~Await] opt
(
FormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
GeneratorMethod [Yield,
Await] :
*
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
GeneratorBody :
FunctionBody [+Yield,
~Await]
YieldExpression [In,
Await] :
yield
yield
[no LineTerminator here]
AssignmentExpression [?In,
+Yield, ?Await]
yield
[no LineTerminator here]
*
AssignmentExpression [?In,
+Yield, ?Await]
注 1
注 2
YieldExpression
不能在生成器函数的 FormalParameters 中使用,因为作为 FormalParameters
一部分的任何表达式都在生成的 Generator 处于可恢复状态之前被求值。
注 3
与 Generators 相关的 抽象操作 在
27.5.3 中定义。
15.5.1 静态语义:早期错误
GeneratorMethod :
*
ClassElementName
(
UniqueFormalParameters
)
{
GeneratorBody
}
GeneratorDeclaration
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
function
*
(
FormalParameters
)
{
GeneratorBody
}
GeneratorExpression
:
function
*
BindingIdentifier opt
(
FormalParameters
)
{
GeneratorBody
}
15.5.2 运行时语义:EvaluateGeneratorBody
语法制导操作
EvaluateGeneratorBody 接受参数 functionObject (一个 ECMAScript 函数对象 )和
argumentsList (一个 List of
ECMAScript 语言值 ),并返回 throw completion 或
return
completion 。它按以下产生式分段定义:
GeneratorBody :
FunctionBody
执行 ? FunctionDeclarationInstantiation (functionObject ,
argumentsList )。
令 G 为 ? OrdinaryCreateFromConstructor (functionObject ,
"%GeneratorPrototype%" , « [[GeneratorState]] , [[GeneratorContext]] , [[GeneratorBrand]] »)。
设置 G .[[GeneratorBrand]] 为
empty 。
设置 G .[[GeneratorState]] 为
suspended-start 。
执行 GeneratorStart (G , FunctionBody )。
返回 ReturnCompletion (G )。
15.5.3 运行时语义:InstantiateGeneratorFunctionObject
语法制导操作
InstantiateGeneratorFunctionObject 接受参数 env (一个 Environment Record )和
privateEnv (一个 PrivateEnvironment Record 或
null ),并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
GeneratorDeclaration
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
令 name 为 BindingIdentifier 的 StringValue 。
令 sourceText 为 GeneratorDeclaration 匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%GeneratorFunction.prototype% ,
sourceText , FormalParameters , GeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
name )。
令 prototype 为 OrdinaryObjectCreate (%GeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 F 。
GeneratorDeclaration
:
function
*
(
FormalParameters
)
{
GeneratorBody
}
令 sourceText 为 GeneratorDeclaration 匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%GeneratorFunction.prototype% ,
sourceText , FormalParameters , GeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
"default" )。
令 prototype 为 OrdinaryObjectCreate (%GeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 F 。
注
匿名的 GeneratorDeclaration 只能作为
export default 声明的一部分出现,因此其函数代码总是 严格模式代码 。
15.5.4 运行时语义:InstantiateGeneratorFunctionExpression
语法制导操作
InstantiateGeneratorFunctionExpression 接受可选参数 name (一个 属性键 或 私有名称 ),并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
GeneratorExpression
:
function
*
(
FormalParameters
)
{
GeneratorBody
}
如果 name 不存在,设置 name 为 "" 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 GeneratorExpression 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%GeneratorFunction.prototype% ,
sourceText , FormalParameters , GeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
令 prototype 为 OrdinaryObjectCreate (%GeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (closure ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 closure 。
GeneratorExpression
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
断言 :name 不存在。
设置 name 为 BindingIdentifier 的 StringValue 。
令 outerEnv 为 运行执行上下文 的 LexicalEnvironment。
令 funcEnv 为 NewDeclarativeEnvironment (outerEnv )。
执行 ! funcEnv .CreateImmutableBinding(name ,
false )。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 GeneratorExpression 匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%GeneratorFunction.prototype% ,
sourceText , FormalParameters , GeneratorBody ,
non-lexical-this , funcEnv , privateEnv )。
执行 SetFunctionName (closure ,
name )。
令 prototype 为 OrdinaryObjectCreate (%GeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (closure ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
执行 ! funcEnv .InitializeBinding(name ,
closure )。
返回 closure 。
注释
15.5.5 运行时语义:Evaluation
GeneratorExpression
:
function
*
BindingIdentifier opt
(
FormalParameters
)
{
GeneratorBody
}
返回 GeneratorExpression 的 InstantiateGeneratorFunctionExpression 。
YieldExpression :
yield
返回 ? Yield (undefined )。
YieldExpression :
yield
AssignmentExpression
令 exprRef 为 ? Evaluation of AssignmentExpression 。
令 value 为 ? GetValue (exprRef )。
返回 ? Yield (value )。
YieldExpression :
yield
*
AssignmentExpression
令 generatorKind 为 GetGeneratorKind ()。
断言 :generatorKind 是
sync 或 async 。
令 exprRef 为 ? Evaluation of AssignmentExpression 。
令 value 为 ? GetValue (exprRef )。
令 iteratorRecord 为 ? GetIterator (value ,
generatorKind )。
令 iterator 为 iteratorRecord .[[Iterator]] 。
令 received 为 NormalCompletion (undefined )。
重复,
如果 received 是一个 normal
completion ,那么
令 innerResult 为 ? Call (iteratorRecord .[[NextMethod]] , iteratorRecord .[[Iterator]] , « received .[[Value]] »)。
如果 generatorKind 是 async ,设置
innerResult 为 ? Await (innerResult )。
如果 innerResult 不是
Object ,抛出 TypeError 异常。
令 done 为 ? IteratorComplete (innerResult )。
如果 done 是 true ,那么
返回 ? IteratorValue (innerResult )。
如果 generatorKind 是 async ,设置
received 为 Completion (AsyncGeneratorYield (?
IteratorValue (innerResult )))。
否则,设置 received 为 Completion (GeneratorYield (innerResult ))。
否则如果 received 是一个 throw
completion ,那么
令 throw 为 ? GetMethod (iterator ,
"throw" )。
如果 throw 不是 undefined ,那么
令 innerResult 为 ? Call (throw ,
iterator , « received .[[Value]] »)。
如果 generatorKind 是 async ,设置
innerResult 为 ? Await (innerResult )。
注释:来自内部 迭代器
throw 方法的异常会被传播。来自内部 throw 方法的
Normal
completion 的处理方式与内部 next 类似。
如果 innerResult 不是
Object ,抛出 TypeError
异常。
令 done 为 ? IteratorComplete (innerResult )。
如果 done 是 true ,那么
返回 ? IteratorValue (innerResult )。
如果 generatorKind 是 async ,设置
received 为 Completion (AsyncGeneratorYield (?
IteratorValue (innerResult )))。
否则,设置 received 为 Completion (GeneratorYield (innerResult ))。
否则,
注释:如果 iterator 没有 throw 方法,这个 throw 将终止
yield* 循环。但首先我们需要给 iterator 一个清理的机会。
令 closeCompletion 为 NormalCompletion (empty )。
如果 generatorKind 是 async ,执行
? AsyncIteratorClose (iteratorRecord ,
closeCompletion )。
否则,执行 ? IteratorClose (iteratorRecord ,
closeCompletion )。
注释:下一步抛出 TypeError 表示存在 yield*
协议违反:iterator 没有 throw 方法。
抛出 TypeError 异常。
否则,
断言 :received 是一个
return
completion 。
令 return 为 ? GetMethod (iterator ,
"return" )。
如果 return 是 undefined ,那么
设置 value 为 received .[[Value]] 。
如果 generatorKind 是 async ,那么
设置 value 为 ? Await (value )。
返回 ReturnCompletion (value )。
令 innerReturnResult 为 ? Call (return ,
iterator , « received .[[Value]] »)。
如果 generatorKind 是 async ,设置
innerReturnResult 为 ? Await (innerReturnResult )。
如果 innerReturnResult 不是
Object ,抛出 TypeError 异常。
令 done 为 ? IteratorComplete (innerReturnResult )。
如果 done 是 true ,那么
设置 value 为 ? IteratorValue (innerReturnResult )。
返回 ReturnCompletion (value )。
如果 generatorKind 是 async ,设置
received 为 Completion (AsyncGeneratorYield (?
IteratorValue (innerReturnResult )))。
否则,设置 received 为 Completion (GeneratorYield (innerReturnResult ))。
15.6 异步生成器函数定义
语法
AsyncGeneratorDeclaration [Yield,
Await, Default] :
async
[no LineTerminator here]
function
*
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
[+Default]
async
[no LineTerminator here]
function
*
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorExpression
:
async
[no LineTerminator here]
function
*
BindingIdentifier [+Yield,
+Await] opt
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorMethod [Yield,
Await] :
async
[no LineTerminator here]
*
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorBody :
FunctionBody [+Yield,
+Await]
注释 1
YieldExpression 和
AwaitExpression
不能在异步生成器函数的 FormalParameters 中使用,因为作为 FormalParameters
一部分的任何表达式都在生成的 AsyncGenerator 处于可恢复状态之前被求值。
注释 2
与 AsyncGenerators 相关的 抽象操作 在
27.6.3 中定义。
15.6.1 静态语义:早期错误
AsyncGeneratorMethod
:
async
*
ClassElementName
(
UniqueFormalParameters
)
{
AsyncGeneratorBody
}
AsyncGeneratorDeclaration
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncGeneratorExpression
:
async
function
*
BindingIdentifier opt
(
FormalParameters
)
{
AsyncGeneratorBody
}
15.6.2 运行时语义:EvaluateAsyncGeneratorBody
语法制导操作
EvaluateAsyncGeneratorBody 接受参数 functionObject (一个 ECMAScript 函数对象 )和
argumentsList (一个 List of
ECMAScript 语言值 ),并返回 throw completion 或
return
completion 。它按以下产生式分段定义:
AsyncGeneratorBody
: FunctionBody
执行 ? FunctionDeclarationInstantiation (functionObject ,
argumentsList )。
令 generator 为 ? OrdinaryCreateFromConstructor (functionObject ,
"%AsyncGeneratorPrototype%" , « [[AsyncGeneratorState]] , [[AsyncGeneratorContext]] , [[AsyncGeneratorQueue]] , [[GeneratorBrand]] »)。
设置 generator .[[GeneratorBrand]] 为
empty 。
设置 generator .[[AsyncGeneratorState]] 为
suspended-start 。
执行 AsyncGeneratorStart (generator ,
FunctionBody )。
返回 ReturnCompletion (generator )。
15.6.3 运行时语义:InstantiateAsyncGeneratorFunctionObject
语法制导操作
InstantiateAsyncGeneratorFunctionObject 接受参数 env (一个 Environment Record )和
privateEnv (一个 PrivateEnvironment Record 或
null ),并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
AsyncGeneratorDeclaration
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
令 name 为 BindingIdentifier 的 StringValue 。
令 sourceText 为 AsyncGeneratorDeclaration
匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%AsyncGeneratorFunction.prototype% ,
sourceText , FormalParameters , AsyncGeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
name )。
令 prototype 为 OrdinaryObjectCreate (%AsyncGeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 F 。
AsyncGeneratorDeclaration
:
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
令 sourceText 为 AsyncGeneratorDeclaration
匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%AsyncGeneratorFunction.prototype% ,
sourceText , FormalParameters , AsyncGeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
"default" )。
令 prototype 为 OrdinaryObjectCreate (%AsyncGeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 F 。
注释
匿名的 AsyncGeneratorDeclaration
只能作为 export default 声明的一部分出现。
15.6.4 运行时语义:InstantiateAsyncGeneratorFunctionExpression
语法制导操作
InstantiateAsyncGeneratorFunctionExpression 接受可选参数 name (一个 属性键 或 私有名称 ),并返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
AsyncGeneratorExpression
:
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
如果 name 不存在,设置 name 为 "" 。
令 env 为 运行执行上下文 的 LexicalEnvironment。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 AsyncGeneratorExpression
匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%AsyncGeneratorFunction.prototype% ,
sourceText , FormalParameters , AsyncGeneratorBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
令 prototype 为 OrdinaryObjectCreate (%AsyncGeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (closure ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
返回 closure 。
AsyncGeneratorExpression
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
断言 :name 不存在。
设置 name 为 BindingIdentifier 的 StringValue 。
令 outerEnv 为 运行执行上下文 的 LexicalEnvironment。
令 funcEnv 为 NewDeclarativeEnvironment (outerEnv )。
执行 ! funcEnv .CreateImmutableBinding(name ,
false )。
令 privateEnv 为 运行执行上下文 的 PrivateEnvironment。
令 sourceText 为 AsyncGeneratorExpression
匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%AsyncGeneratorFunction.prototype% ,
sourceText , FormalParameters , AsyncGeneratorBody ,
non-lexical-this , funcEnv , privateEnv )。
执行 SetFunctionName (closure ,
name )。
令 prototype 为 OrdinaryObjectCreate (%AsyncGeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (closure ,
"prototype" , PropertyDescriptor { [[Value]] :
prototype , [[Writable]] : true ,
[[Enumerable]] : false , [[Configurable]] : false })。
执行 ! funcEnv .InitializeBinding(name ,
closure )。
返回 closure 。
注释
15.6.5 运行时语义:Evaluation
AsyncGeneratorExpression
:
async
function
*
BindingIdentifier opt
(
FormalParameters
)
{
AsyncGeneratorBody
}
返回 AsyncGeneratorExpression 的
InstantiateAsyncGeneratorFunctionExpression 。
15.7 类定义
语法
ClassDeclaration [Yield, Await,
Default] :
class
BindingIdentifier [?Yield,
?Await]
ClassTail [?Yield,
?Await]
[+Default]
class
ClassTail [?Yield,
?Await]
ClassExpression [Yield,
Await] :
class
BindingIdentifier [?Yield,
?Await] opt
ClassTail [?Yield,
?Await]
ClassTail [Yield,
Await] :
ClassHeritage [?Yield,
?Await] opt
{
ClassBody [?Yield,
?Await] opt
}
ClassHeritage [Yield,
Await] :
extends
LeftHandSideExpression [?Yield,
?Await]
ClassBody [Yield,
Await] :
ClassElementList [?Yield,
?Await]
ClassElementList [Yield,
Await] :
ClassElement [?Yield,
?Await]
ClassElementList [?Yield,
?Await]
ClassElement [?Yield,
?Await]
ClassElement [Yield,
Await] :
MethodDefinition [?Yield,
?Await]
static
MethodDefinition [?Yield,
?Await]
FieldDefinition [?Yield,
?Await]
;
static
FieldDefinition [?Yield,
?Await]
;
ClassStaticBlock
;
FieldDefinition [Yield,
Await] :
ClassElementName [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
ClassElementName [Yield,
Await] :
PropertyName [?Yield,
?Await]
PrivateIdentifier
ClassStaticBlock :
static
{
ClassStaticBlockBody
}
ClassStaticBlockBody
:
ClassStaticBlockStatementList
ClassStaticBlockStatementList
:
StatementList [~Yield, +Await,
~Return] opt
注释
15.7.1 静态语义:早期错误
ClassTail :
ClassHeritage opt
{
ClassBody
}
ClassBody : ClassElementList
ClassElement : MethodDefinition
ClassElement :
static
MethodDefinition
ClassElement :
FieldDefinition
;
ClassElement :
static
FieldDefinition
;
FieldDefinition :
ClassElementName
Initializer opt
ClassElementName :
PrivateIdentifier
ClassStaticBlockBody
: ClassStaticBlockStatementList
15.7.2 静态语义:ClassElementKind
语法制导操作
ClassElementKind 不接受参数,返回
constructor-method 、non-constructor-method 或
empty 。它按以下产生式分段定义:
ClassElement : MethodDefinition
如果 MethodDefinition 的 PropName 是
"constructor" ,返回 constructor-method 。
返回 non-constructor-method 。
ClassElement :
static
MethodDefinition
FieldDefinition
;
static
FieldDefinition
;
返回 non-constructor-method 。
ClassElement : ClassStaticBlock
返回 non-constructor-method 。
ClassElement : ;
返回 empty 。
15.7.3 静态语义:ConstructorMethod
语法制导操作
ConstructorMethod 不接受参数,返回一个 ClassElement 解析节点 或
empty 。它按以下产生式分段定义:
ClassElementList :
ClassElement
如果 ClassElement 的
ClassElementKind 是
constructor-method ,返回 ClassElement 。
返回 empty 。
ClassElementList :
ClassElementList
ClassElement
令 head 为 ClassElementList 的 ConstructorMethod 。
如果 head 不是 empty ,返回 head 。
如果 ClassElement 的
ClassElementKind 是
constructor-method ,返回 ClassElement 。
返回 empty 。
注释
早期错误规则确保只有一个名为 "constructor" 的方法定义,并且它不是 访问器属性 或生成器定义。
15.7.4 静态语义:IsStatic
语法制导操作
IsStatic 不接受参数,返回一个布尔值。它按以下产生式分段定义:
ClassElement : MethodDefinition
返回 false 。
ClassElement :
static
MethodDefinition
返回 true 。
ClassElement :
FieldDefinition
;
返回 false 。
ClassElement :
static
FieldDefinition
;
返回 true 。
ClassElement : ClassStaticBlock
返回 true 。
ClassElement : ;
返回 false 。
15.7.5 静态语义:NonConstructorElements
语法制导操作
NonConstructorElements 不接受参数,返回一个 List of
ClassElement 解析节点 。它按以下产生式分段定义:
ClassElementList :
ClassElement
如果 ClassElement 的
ClassElementKind 是
non-constructor-method ,则
返回 « ClassElement »。
返回一个新的空 List 。
ClassElementList :
ClassElementList
ClassElement
令 list 为 ClassElementList 的 NonConstructorElements 。
如果 ClassElement 的
ClassElementKind 是
non-constructor-method ,则
将 ClassElement
追加到 list 的末尾。
返回 list 。
15.7.6 静态语义:PrototypePropertyNameList
语法制导操作
PrototypePropertyNameList 不接受参数,返回一个 List of
属性键 。它按以下产生式分段定义:
ClassElementList :
ClassElement
令 propName 为 ClassElement 的 PropName 。
如果 propName 是 empty ,返回一个新的空 List 。
如果 ClassElement 的
IsStatic 是
true ,返回一个新的空 List 。
返回 « propName »。
ClassElementList :
ClassElementList
ClassElement
令 list 为 ClassElementList 的 PrototypePropertyNameList 。
令 propName 为 ClassElement 的 PropName 。
如果 propName 是 empty ,返回 list 。
如果 ClassElement 的
IsStatic 是
true ,返回 list 。
返回 list 和 « propName » 的 列表连接 。
15.7.7 静态语义:AllPrivateIdentifiersValid
语法制导操作
AllPrivateIdentifiersValid 接受参数 names (一个 List of Strings),返回一个布尔值。
本规范中每个未在下面列出的语法产生式替代都隐含地具有以下 AllPrivateIdentifiersValid 的默认定义:
对于此 解析节点 的每个子节点 child ,执行
如果 child 是非终结符的实例,则
如果 child 的 AllPrivateIdentifiersValid
在参数 names 下是 false ,返回
false 。
返回 true 。
MemberExpression :
MemberExpression
.
PrivateIdentifier
如果 names 包含 PrivateIdentifier 的 StringValue ,则
返回 MemberExpression 的 AllPrivateIdentifiersValid
在参数 names 下的结果。
返回 false 。
CallExpression :
CallExpression
.
PrivateIdentifier
如果 names 包含 PrivateIdentifier 的 StringValue ,则
返回 CallExpression 的 AllPrivateIdentifiersValid
在参数 names 下的结果。
返回 false 。
OptionalChain :
?.
PrivateIdentifier
如果 names 包含 PrivateIdentifier 的 StringValue ,返回
true 。
返回 false 。
OptionalChain :
OptionalChain
.
PrivateIdentifier
如果 names 包含 PrivateIdentifier 的 StringValue ,则
返回 OptionalChain 的 AllPrivateIdentifiersValid
在参数 names 下的结果。
返回 false 。
ClassBody : ClassElementList
令 newNames 为 names 和 ClassBody 的 PrivateBoundIdentifiers
的 列表连接 。
返回 ClassElementList 的 AllPrivateIdentifiersValid
在参数 newNames 下的结果。
RelationalExpression
:
PrivateIdentifier
in
ShiftExpression
如果 names 包含 PrivateIdentifier 的 StringValue ,则
返回 ShiftExpression 的 AllPrivateIdentifiersValid
在参数 names 下的结果。
返回 false 。
15.7.8 静态语义:PrivateBoundIdentifiers
语法制导操作
PrivateBoundIdentifiers 不接受参数,返回一个 List of
Strings。它按以下产生式分段定义:
FieldDefinition :
ClassElementName
Initializer opt
返回 ClassElementName 的 PrivateBoundIdentifiers 。
ClassElementName :
PrivateIdentifier
返回一个 List ,其唯一元素是
PrivateIdentifier
的 StringValue 。
ClassElementName :
PropertyName
ClassElement :
ClassStaticBlock
;
返回一个新的空 List 。
ClassElementList :
ClassElementList
ClassElement
令 names1 为 ClassElementList 的 PrivateBoundIdentifiers 。
令 names2 为 ClassElement 的 PrivateBoundIdentifiers 。
返回 names1 和 names2 的 列表连接 。
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
get
ClassElementName
(
)
{
FunctionBody
}
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
GeneratorMethod :
*
ClassElementName
(
UniqueFormalParameters
)
{
GeneratorBody
}
AsyncMethod :
async
ClassElementName
(
UniqueFormalParameters
)
{
AsyncFunctionBody
}
AsyncGeneratorMethod
:
async
*
ClassElementName
(
UniqueFormalParameters
)
{
AsyncGeneratorBody
}
返回 ClassElementName 的 PrivateBoundIdentifiers 。
15.7.9 静态语义:ContainsArguments
语法制导操作
ContainsArguments 不接受参数,返回一个布尔值。
本规范中每个未在下面列出的语法产生式替代都隐含地具有以下 ContainsArguments 的默认定义:
对于此 解析节点 的每个子节点 child ,执行
如果 child 是非终结符的实例,则
如果 child 的 ContainsArguments
是 true ,返回 true 。
返回 false 。
IdentifierReference
: Identifier
如果 Identifier 的
StringValue 是
"arguments" ,返回 true 。
返回 false 。
FunctionDeclaration
:
function
BindingIdentifier
(
FormalParameters
)
{
FunctionBody
}
function
(
FormalParameters
)
{
FunctionBody
}
FunctionExpression
:
function
BindingIdentifier opt
(
FormalParameters
)
{
FunctionBody
}
GeneratorDeclaration
:
function
*
BindingIdentifier
(
FormalParameters
)
{
GeneratorBody
}
function
*
(
FormalParameters
)
{
GeneratorBody
}
GeneratorExpression
:
function
*
BindingIdentifier opt
(
FormalParameters
)
{
GeneratorBody
}
AsyncGeneratorDeclaration
:
async
function
*
BindingIdentifier
(
FormalParameters
)
{
AsyncGeneratorBody
}
async
function
*
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncGeneratorExpression
:
async
function
*
BindingIdentifier opt
(
FormalParameters
)
{
AsyncGeneratorBody
}
AsyncFunctionDeclaration
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
AsyncFunctionExpression
:
async
function
BindingIdentifier opt
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 false 。
MethodDefinition :
ClassElementName
(
UniqueFormalParameters
)
{
FunctionBody
}
get
ClassElementName
(
)
{
FunctionBody
}
set
ClassElementName
(
PropertySetParameterList
)
{
FunctionBody
}
GeneratorMethod :
*
ClassElementName
(
UniqueFormalParameters
)
{
GeneratorBody
}
AsyncGeneratorMethod
:
async
*
ClassElementName
(
UniqueFormalParameters
)
{
AsyncGeneratorBody
}
AsyncMethod :
async
ClassElementName
(
UniqueFormalParameters
)
{
AsyncFunctionBody
}
返回 ClassElementName 的 ContainsArguments 。
15.7.10 运行时语义:ClassFieldDefinitionEvaluation
语法制导操作
ClassFieldDefinitionEvaluation 接受参数 homeObject (一个 Object),返回一个 正常完成包含 一个 ClassFieldDefinition
Record 或一个 突然完成 。它按以下产生式分段定义:
FieldDefinition :
ClassElementName
Initializer opt
令 name 为 ? ClassElementName 的 Evaluation 。
如果 Initializer 存在,则
令 formalParameterList 为产生式
FormalParameters
: [empty]
的一个实例。
令 env 为 正在运行的执行上下文 的
LexicalEnvironment。
令 privateEnv 为 正在运行的执行上下文 的
PrivateEnvironment。
令 sourceText 为空的 Unicode 代码点序列。
令 initializer 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , formalParameterList , Initializer ,
non-lexical-this , env , privateEnv )。
执行 MakeMethod (initializer ,
homeObject )。
设置 initializer .[[ClassFieldInitializerName]]
为 name 。
否则,
令 initializer 为 empty 。
返回 ClassFieldDefinition
Record { [[Name]] : name , [[Initializer]] : initializer }。
注释
为 initializer 创建的函数永远不能被 ECMAScript 代码直接访问。
15.7.11 运行时语义:ClassStaticBlockDefinitionEvaluation
语法制导操作
ClassStaticBlockDefinitionEvaluation 接受参数 homeObject (一个 Object),返回一个 ClassStaticBlockDefinition
Record 。它按以下产生式分段定义:
ClassStaticBlock :
static
{
ClassStaticBlockBody
}
令 lex 为 正在运行的执行上下文 的
LexicalEnvironment。
令 privateEnv 为 正在运行的执行上下文 的
PrivateEnvironment。
令 sourceText 为空的 Unicode 代码点序列。
令 formalParameters 为产生式
FormalParameters
: [empty]
的一个实例。
令 bodyFunction 为 OrdinaryFunctionCreate (%Function.prototype% ,
sourceText , formalParameters , ClassStaticBlockBody ,
non-lexical-this , lex , privateEnv )。
执行 MakeMethod (bodyFunction ,
homeObject )。
返回 ClassStaticBlockDefinition
Record { [[BodyFunction]] :
bodyFunction }。
注释
函数 bodyFunction 永远不能被 ECMAScript 代码直接访问。
15.7.12 运行时语义:EvaluateClassStaticBlockBody
语法制导操作
EvaluateClassStaticBlockBody 接受参数 functionObject (一个 ECMAScript 函数对象 ),返回一个
返回完成 或一个 抛出完成 。它按以下产生式分段定义:
ClassStaticBlockBody
: ClassStaticBlockStatementList
断言 :functionObject 是由 ClassStaticBlockDefinitionEvaluation
步骤 5 创建的合成函数。
执行 ! FunctionDeclarationInstantiation (functionObject ,
« »)。
执行 ? ClassStaticBlockStatementList
的 Evaluation 。
返回 ReturnCompletion (undefined )。
15.7.13 运行时语义:ClassElementEvaluation
语法制导操作
ClassElementEvaluation 接受参数 object (一个 Object),返回一个 正常完成包含 一个 ClassFieldDefinition
Record 、一个 ClassStaticBlockDefinition
Record 、一个 PrivateElement 或
unused ,或一个 突然完成 。它按以下产生式分段定义:
ClassElement :
FieldDefinition
;
static
FieldDefinition
;
返回 ? FieldDefinition 的 ClassFieldDefinitionEvaluation ,参数为
object 。
ClassElement :
MethodDefinition
static
MethodDefinition
返回 ? MethodDefinition 的 MethodDefinitionEvaluation ,参数为
object 和 false 。
ClassElement : ClassStaticBlock
返回 ClassStaticBlock 的 ClassStaticBlockDefinitionEvaluation ,参数为
object 。
ClassElement : ;
返回 unused 。
15.7.14 运行时语义:ClassDefinitionEvaluation
语法制导操作
ClassDefinitionEvaluation 接受参数 classBinding (一个 String 或
undefined )和 className (一个 属性键 或一个 Private
Name ),返回一个 正常完成包含 一个
函数对象
或一个 突然完成 。
注释
为了便于规范,私有方法和访问器与私有字段一起包含在类实例的 [[PrivateElements]]
槽中。但是,任何给定对象要么拥有给定类定义的所有私有方法和访问器,要么一个都没有。这个特性的设计使得实现可以选择使用不需要单独跟踪每个方法或访问器的策略来实现私有方法和访问器。
例如,实现可以直接将实例私有方法与其相应的 Private Name 关联,并为每个对象跟踪哪些类 构造函数
曾以该对象作为其 this 值运行过。然后在对象上查找实例私有方法就包括检查定义该方法的类 构造函数 是否已被用于初始化该对象,然后返回与
Private
Name 关联的方法。
这与私有字段不同:因为字段初始化器可能在类实例化期间抛出异常,单个对象可能拥有给定类的私有字段的某个真子集,因此私有字段通常必须单独跟踪。
它按以下产生式分段定义:
ClassTail :
ClassHeritage opt
{
ClassBody opt
}
令 env 为 正在运行的执行上下文 的
LexicalEnvironment。
令 classEnv 为 NewDeclarativeEnvironment (env )。
如果 classBinding 不是 undefined ,则
执行 ! classEnv .CreateImmutableBinding(classBinding ,
true )。
令 outerPrivateEnvironment 为 正在运行的执行上下文 的
PrivateEnvironment。
令 classPrivateEnvironment 为 NewPrivateEnvironment (outerPrivateEnvironment )。
如果 ClassBody 存在,则
对于 ClassBody 的
PrivateBoundIdentifiers
中的每个 String dn ,执行
如果 classPrivateEnvironment .[[Names]]
包含一个 Private Name
pn 使得 pn .[[Description]]
是 dn ,则
断言 :这只可能发生在 getter/setter
对。
否则,
令 name 为一个新的 Private
Name ,其 [[Description]] 是 dn 。
将 name 追加到 classPrivateEnvironment .[[Names]] 。
如果 ClassHeritage
不存在,则
令 protoParent 为 %Object.prototype% 。
令 constructorParent 为 %Function.prototype% 。
否则,
设置 正在运行的执行上下文 的
LexicalEnvironment 为 classEnv 。
注释:当求值 ClassHeritage 时,正在运行的执行上下文 的
PrivateEnvironment 是 outerPrivateEnvironment 。
令 superclassRef 为 Completion (ClassHeritage 的
Evaluation )。
设置 正在运行的执行上下文 的
LexicalEnvironment 为 env 。
令 superclass 为 ? GetValue (?
superclassRef )。
如果 superclass 是 null ,则
令 protoParent 为 null 。
令 constructorParent 为 %Function.prototype% 。
否则,如果 IsConstructor (superclass )
是 false ,则
抛出 TypeError 异常。
否则,
令 protoParent 为 ? Get (superclass ,
"prototype" )。
如果 protoParent 不是对象 且
protoParent 不是 null ,抛出
TypeError 异常。
令 constructorParent 为 superclass 。
令 proto 为 OrdinaryObjectCreate (protoParent )。
如果 ClassBody 不存在,令
constructor 为 empty 。
否则,令 constructor 为 ClassBody 的 ConstructorMethod 。
设置 正在运行的执行上下文 的 LexicalEnvironment
为 classEnv 。
设置 正在运行的执行上下文 的 PrivateEnvironment
为 classPrivateEnvironment 。
如果 constructor 是 empty ,则
令 defaultConstructor 为一个新的 抽象闭包 ,不接受参数,不捕获任何值,调用时执行以下步骤:
令 args 为通过 [[Call]] 或 [[Construct]] 传递给此函数的参数 List 。
如果 NewTarget 是 undefined ,抛出
TypeError 异常。
令 F 为 活跃函数对象 。
如果 F .[[ConstructorKind]] 是
derived ,则
注释:此分支的行为类似于
constructor(...args) { super(...args); }。最显著的区别是,虽然前述
ECMAScript 源文本
会可观察地调用 %Array.prototype% 上的 %Symbol.iterator%
方法,但此函数不会。
令 func 为 ! F .[[GetPrototypeOf]] ()。
如果 IsConstructor (func )
是 false ,抛出 TypeError 异常。
令 result 为 ? Construct (func ,
args , NewTarget)。
否则,
注释:此分支的行为类似于 constructor() {}。
令 result 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%Object.prototype%" )。
执行 ? InitializeInstanceElements (result ,
F )。
返回 result 。
令 F 为 CreateBuiltinFunction (defaultConstructor ,
0, className , « [[ConstructorKind]] , [[SourceText]] », 当前 Realm Record ,
constructorParent )。
否则,
令 constructorInfo 为 ! constructor 的 DefineMethod ,参数为
proto 和 constructorParent 。
令 F 为 constructorInfo .[[Closure]] 。
执行 MakeClassConstructor (F )。
执行 SetFunctionName (F ,
className )。
执行 MakeConstructor (F ,
false , proto )。
如果 ClassHeritage
存在,设置 F .[[ConstructorKind]] 为
derived 。
执行 ! DefineMethodProperty (proto ,
"constructor" , F , false )。
如果 ClassBody 不存在,令
elements 为一个新的空 List 。
否则,令 elements 为 ClassBody 的 NonConstructorElements 。
令 instancePrivateMethods 为一个新的空 List 。
令 staticPrivateMethods 为一个新的空 List 。
令 instanceFields 为一个新的空 List 。
令 staticElements 为一个新的空 List 。
对于 elements 中的每个 ClassElement e ,执行
如果 e 的 IsStatic 是
false ,则
令 element 为 Completion (e
的 ClassElementEvaluation ,参数为
proto )。
否则,
令 element 为 Completion (e
的 ClassElementEvaluation ,参数为
F )。
如果 element 是一个 突然完成 ,则
设置 正在运行的执行上下文 的
LexicalEnvironment 为 env 。
设置 正在运行的执行上下文 的
PrivateEnvironment 为 outerPrivateEnvironment 。
返回 ? element 。
设置 element 为 ! element 。
如果 element 是一个 PrivateElement ,则
断言 :element .[[Kind]] 是 method 或
accessor 。
如果 e 的 IsStatic 是
false ,令 container 为
instancePrivateMethods 。
否则,令 container 为 staticPrivateMethods 。
如果 container 包含一个 PrivateElement
pe 使得 pe .[[Key]] 是
element .[[Key]] ,则
断言 :element .[[Kind]] 和 pe .[[Kind]] 都是
accessor 。
如果 element .[[Get]] 是
undefined ,则
令 combined 为 PrivateElement
{ [[Key]] :
element .[[Key]] ,
[[Kind]] :
accessor , [[Get]] : pe .[[Get]] , [[Set]] : element .[[Set]] }。
否则,
令 combined 为 PrivateElement
{ [[Key]] :
element .[[Key]] ,
[[Kind]] :
accessor , [[Get]] : element .[[Get]] , [[Set]] : pe .[[Set]] }。
在 container 中将 pe 替换为 combined 。
否则,
将 element 追加到 container 。
否则,如果 element 是一个 ClassFieldDefinition
Record ,则
如果 e 的 IsStatic 是
false ,将 element 追加到
instanceFields 。
否则,将 element 追加到 staticElements 。
否则,如果 element 是一个 ClassStaticBlockDefinition
Record ,则
将 element 追加到 staticElements 。
设置 正在运行的执行上下文 的 LexicalEnvironment
为 env 。
如果 classBinding 不是 undefined ,则
执行 ! classEnv .InitializeBinding(classBinding ,
F )。
设置 F .[[PrivateMethods]] 为
instancePrivateMethods 。
设置 F .[[Fields]] 为 instanceFields 。
对于 staticPrivateMethods 中的每个 PrivateElement
method ,执行
执行 ! PrivateMethodOrAccessorAdd (F ,
method )。
对于 staticElements 中的每个元素 elementRecord ,执行
如果 elementRecord 是一个 ClassFieldDefinition
Record ,则
令 result 为 Completion (DefineField (F ,
elementRecord ))。
否则,
断言 :elementRecord 是一个
ClassStaticBlockDefinition
Record 。
令 result 为 Completion (Call (elementRecord .[[BodyFunction]] , F ))。
如果 result 是一个 突然完成 ,则
设置 正在运行的执行上下文 的
PrivateEnvironment 为 outerPrivateEnvironment 。
返回 ? result 。
设置 正在运行的执行上下文 的 PrivateEnvironment
为 outerPrivateEnvironment 。
返回 F 。
15.7.15 运行时语义:BindingClassDeclarationEvaluation
语法制导操作
BindingClassDeclarationEvaluation 不接受参数,返回一个 正常完成包含 一个 函数对象 或一个
突然完成 。它按以下产生式分段定义:
ClassDeclaration :
class
BindingIdentifier
ClassTail
令 className 为 BindingIdentifier 的 StringValue 。
令 value 为 ? ClassTail 的 ClassDefinitionEvaluation ,参数为
className 和 className 。
设置 value .[[SourceText]] 为 ClassDeclaration 匹配的源文本 。
令 env 为 正在运行的执行上下文 的
LexicalEnvironment。
执行 ? InitializeBoundName (className ,
value , env )。
返回 value 。
ClassDeclaration :
class
ClassTail
令 value 为 ? ClassTail 的 ClassDefinitionEvaluation ,参数为
undefined 和 "default" 。
设置 value .[[SourceText]] 为 ClassDeclaration 匹配的源文本 。
返回 value 。
注释
ClassDeclaration
:
class
ClassTail
只作为 ExportDeclaration
的一部分出现,其绑定的建立作为该产生式的求值操作的一部分处理。参见 16.2.3.7 。
15.7.16 运行时语义:Evaluation
ClassDeclaration :
class
BindingIdentifier
ClassTail
执行 ? 此 ClassDeclaration 的 BindingClassDeclarationEvaluation 。
返回 empty 。
注释
ClassExpression :
class
ClassTail
令 value 为 ? ClassTail 的 ClassDefinitionEvaluation ,参数为
undefined 和 "" 。
设置 value .[[SourceText]] 为 ClassExpression 匹配的源文本 。
返回 value 。
ClassExpression :
class
BindingIdentifier
ClassTail
令 className 为 BindingIdentifier 的 StringValue 。
令 value 为 ? ClassTail 的 ClassDefinitionEvaluation ,参数为
className 和 className 。
设置 value .[[SourceText]] 为 ClassExpression 匹配的源文本 。
返回 value 。
ClassElementName :
PrivateIdentifier
令 privateIdentifier 为 PrivateIdentifier 的 StringValue 。
令 privateEnvRec 为 正在运行的执行上下文 的
PrivateEnvironment。
令 names 为 privateEnvRec .[[Names]] 。
断言 :names 中恰好有一个元素是 Private
Name ,其 [[Description]] 是
privateIdentifier 。
令 privateName 为 names 中 [[Description]] 是
privateIdentifier 的 Private Name 。
返回 privateName 。
ClassStaticBlockStatementList
: [empty]
返回 undefined 。
15.8 异步函数定义
语法
AsyncFunctionDeclaration [Yield,
Await, Default] :
async
[no LineTerminator here]
function
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
[+Default]
async
[no LineTerminator here]
function
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncFunctionExpression
:
async
[no LineTerminator here]
function
BindingIdentifier [~Yield,
+Await] opt
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncMethod [Yield,
Await] :
async
[no LineTerminator here]
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncFunctionBody :
FunctionBody [~Yield,
+Await]
AwaitExpression [Yield]
:
await
UnaryExpression [?Yield,
+Await]
注释 1
当存在 [Await] 参数时,await 被解析为 AwaitExpression 的关键字 。[Await]
参数在以下上下文的顶层存在,尽管根据非终结符(如 FunctionBody ),在某些上下文中该参数可能不存在:
当 Script 是语法目标符号 时,当不存在 [Await]
参数时,await 可能被解析为标识符。这包括以下上下文:
注释 2
与 YieldExpression 不同,省略
AwaitExpression
的操作数是语法错误。你必须等待某些东西。
15.8.1 静态语义:早期错误
AsyncMethod :
async
ClassElementName
(
UniqueFormalParameters
)
{
AsyncFunctionBody
}
AsyncFunctionDeclaration
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
AsyncFunctionExpression
:
async
function
BindingIdentifier opt
(
FormalParameters
)
{
AsyncFunctionBody
}
15.8.2 运行时语义:InstantiateAsyncFunctionObject
语法制导操作
InstantiateAsyncFunctionObject 接受参数 env (一个 Environment Record )和
privateEnv (一个 PrivateEnvironment Record 或
null ),返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
AsyncFunctionDeclaration
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
令 name 为 BindingIdentifier 的 StringValue 。
令 sourceText 为 AsyncFunctionDeclaration
匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , FormalParameters , AsyncFunctionBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
name )。
返回 F 。
AsyncFunctionDeclaration
:
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
令 sourceText 为 AsyncFunctionDeclaration
匹配的源文本 。
令 F 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , FormalParameters , AsyncFunctionBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
"default" )。
返回 F 。
15.8.3 运行时语义:InstantiateAsyncFunctionExpression
语法制导操作
InstantiateAsyncFunctionExpression 接受可选参数 name (一个 属性键 或一个 Private
Name ),返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
AsyncFunctionExpression
:
async
function
(
FormalParameters
)
{
AsyncFunctionBody
}
如果 name 不存在,设置 name 为 "" 。
令 env 为 正在运行的执行上下文 的
LexicalEnvironment。
令 privateEnv 为 正在运行的执行上下文 的
PrivateEnvironment。
令 sourceText 为 AsyncFunctionExpression
匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , FormalParameters , AsyncFunctionBody ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
返回 closure 。
AsyncFunctionExpression
:
async
function
BindingIdentifier
(
FormalParameters
)
{
AsyncFunctionBody
}
断言 :name 不存在。
设置 name 为 BindingIdentifier 的 StringValue 。
令 outerEnv 为 正在运行的执行上下文 的
LexicalEnvironment。
令 funcEnv 为 NewDeclarativeEnvironment (outerEnv )。
执行 ! funcEnv .CreateImmutableBinding(name ,
false )。
令 privateEnv 为 正在运行的执行上下文 的
PrivateEnvironment。
令 sourceText 为 AsyncFunctionExpression
匹配的源文本 。
令 closure 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , FormalParameters , AsyncFunctionBody ,
non-lexical-this , funcEnv , privateEnv )。
执行 SetFunctionName (closure ,
name )。
执行 ! funcEnv .InitializeBinding(name , closure )。
返回 closure 。
注释
15.8.4 运行时语义:EvaluateAsyncFunctionBody
语法制导操作
EvaluateAsyncFunctionBody 接受参数 functionObject (一个 ECMAScript 函数对象 )和
argumentsList (一个 List of
ECMAScript 语言值 ),返回一个 返回完成 。它按以下产生式分段定义:
AsyncFunctionBody
: FunctionBody
令 promiseCapability 为 ! NewPromiseCapability (%Promise% )。
令 completion 为 Completion (FunctionDeclarationInstantiation (functionObject ,
argumentsList ))。
如果 completion 是一个 突然完成 ,则
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
completion .[[Value]] »)。
否则,
执行 AsyncFunctionStart (promiseCapability ,
FunctionBody )。
返回 ReturnCompletion (promiseCapability .[[Promise]] )。
15.8.5 运行时语义:Evaluation
AsyncFunctionExpression
:
async
function
BindingIdentifier opt
(
FormalParameters
)
{
AsyncFunctionBody
}
返回 AsyncFunctionExpression 的
InstantiateAsyncFunctionExpression 。
AwaitExpression :
await
UnaryExpression
令 exprRef 为 ? UnaryExpression 的 Evaluation 。
令 value 为 ? GetValue (exprRef )。
返回 ? Await (value )。
15.9 异步箭头函数定义
语法
AsyncArrowFunction [In, Yield,
Await] :
async
[no LineTerminator here]
AsyncArrowBindingIdentifier [?Yield]
[no LineTerminator here]
=>
AsyncConciseBody [?In]
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
[no LineTerminator here]
=>
AsyncConciseBody [?In]
AsyncConciseBody [In]
:
[lookahead ≠ { ]
ExpressionBody [?In,
+Await]
{
AsyncFunctionBody
}
AsyncArrowBindingIdentifier [Yield]
:
BindingIdentifier [?Yield,
+Await]
CoverCallExpressionAndAsyncArrowHead [Yield,
Await] :
MemberExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
补充语法
当处理产生式实例
AsyncArrowFunction
:
CoverCallExpressionAndAsyncArrowHead
=>
AsyncConciseBody
时,使用以下语法来细化对 CoverCallExpressionAndAsyncArrowHead
的解释:
AsyncArrowHead :
async
[no LineTerminator here]
ArrowFormalParameters [~Yield,
+Await]
15.9.1 静态语义:早期错误
AsyncArrowFunction
:
async
AsyncArrowBindingIdentifier
=>
AsyncConciseBody
AsyncArrowFunction
:
CoverCallExpressionAndAsyncArrowHead
=>
AsyncConciseBody
15.9.2 静态语义:AsyncConciseBodyContainsUseStrict
语法制导操作
AsyncConciseBodyContainsUseStrict 不接受参数,返回一个 Boolean。它按以下产生式分段定义:
AsyncConciseBody :
ExpressionBody
返回 false 。
AsyncConciseBody :
{
AsyncFunctionBody
}
返回 AsyncFunctionBody 的 FunctionBodyContainsUseStrict 。
15.9.3 运行时语义:EvaluateAsyncConciseBody
语法制导操作
EvaluateAsyncConciseBody 接受参数 functionObject (一个 ECMAScript 函数对象 )和
argumentsList (一个 List of
ECMAScript 语言值 ),返回一个 返回完成 。它按以下产生式分段定义:
AsyncConciseBody :
ExpressionBody
令 promiseCapability 为 ! NewPromiseCapability (%Promise% )。
令 completion 为 Completion (FunctionDeclarationInstantiation (functionObject ,
argumentsList ))。
如果 completion 是一个 突然完成 ,则
执行 ! Call (promiseCapability .[[Reject]] , undefined , «
completion .[[Value]] »)。
否则,
执行 AsyncFunctionStart (promiseCapability ,
ExpressionBody )。
返回 ReturnCompletion (promiseCapability .[[Promise]] )。
15.9.4 运行时语义:InstantiateAsyncArrowFunctionExpression
语法制导操作
InstantiateAsyncArrowFunctionExpression 接受可选参数 name (一个 属性键 或一个 Private
Name ),返回一个 ECMAScript 函数对象 。它按以下产生式分段定义:
AsyncArrowFunction
:
async
AsyncArrowBindingIdentifier
=>
AsyncConciseBody
如果 name 不存在,设置 name 为 "" 。
令 env 为 正在运行的执行上下文 的
LexicalEnvironment。
令 privateEnv 为 正在运行的执行上下文 的
PrivateEnvironment。
令 sourceText 为 AsyncArrowFunction 匹配的源文本 。
令 parameters 为 AsyncArrowBindingIdentifier 。
令 closure 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , parameters , AsyncConciseBody ,
lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
返回 closure 。
AsyncArrowFunction
:
CoverCallExpressionAndAsyncArrowHead
=>
AsyncConciseBody
如果 name 不存在,设置 name 为 "" 。
令 env 为 正在运行的执行上下文 的
LexicalEnvironment。
令 privateEnv 为 正在运行的执行上下文 的
PrivateEnvironment。
令 sourceText 为 AsyncArrowFunction 匹配的源文本 。
令 head 为被 CoverCallExpressionAndAsyncArrowHead
覆盖 的 AsyncArrowHead 。
令 parameters 为 head 的 ArrowFormalParameters 。
令 closure 为 OrdinaryFunctionCreate (%AsyncFunction.prototype% ,
sourceText , parameters , AsyncConciseBody ,
lexical-this , env , privateEnv )。
执行 SetFunctionName (closure ,
name )。
返回 closure 。
15.9.5 运行时语义:Evaluation
AsyncArrowFunction
:
async
AsyncArrowBindingIdentifier
=>
AsyncConciseBody
CoverCallExpressionAndAsyncArrowHead
=>
AsyncConciseBody
返回 AsyncArrowFunction 的 InstantiateAsyncArrowFunctionExpression 。
15.10 尾位置调用
15.10.1 静态语义:IsInTailPosition ( call )
抽象操作 IsInTailPosition 接受参数 call (一个 CallExpression 解析节点 、一个 MemberExpression 解析节点 ,或一个 OptionalChain 解析节点 ),返回一个 Boolean。调用时执行以下步骤:
如果 IsStrict (call ) 是
false ,返回 false 。
如果 call 不包含在 FunctionBody 、ConciseBody 或 AsyncConciseBody 中,返回
false 。
令 body 为最紧密包含 call 的 FunctionBody 、ConciseBody 或 AsyncConciseBody 。
如果 body 是 GeneratorBody 的 FunctionBody ,返回
false 。
如果 body 是 AsyncFunctionBody 的 FunctionBody ,返回
false 。
如果 body 是 AsyncGeneratorBody 的 FunctionBody ,返回
false 。
如果 body 是 AsyncConciseBody ,返回
false 。
返回 body 以参数 call 进行的 HasCallInTailPosition
的结果。
注释
尾位置调用仅在 严格模式代码 中定义,因为有一个常见的非标准语言扩展(参见
10.2.4 )可以观察调用者上下文链。
15.10.2 静态语义:HasCallInTailPosition
语法制导操作
HasCallInTailPosition 接受参数 call (一个 CallExpression 解析节点 、一个 MemberExpression 解析节点 ,或一个 OptionalChain 解析节点 ),返回一个 Boolean。
注释 1
call 是一个 解析节点 ,表示特定范围的源文本。当以下算法将
call 与另一个 解析节点 进行比较时,这是测试它们是否表示相同的源文本。
注释 2
紧接着返回调用结果的 GetValue 的潜在尾位置调用也是可能的尾位置调用。函数调用不能返回
Reference
Record ,因此这样的 GetValue 操作将总是返回与实际函数调用结果相同的值。
它按以下产生式分段定义:
StatementList :
StatementList
StatementListItem
令 has 为 StatementList 以参数 call 进行的
HasCallInTailPosition 。
如果 has 是 true ,返回 true 。
返回 StatementListItem 以参数
call 进行的 HasCallInTailPosition 。
FunctionStatementList
:
[empty]
StatementListItem
:
Declaration
Statement :
VariableStatement
EmptyStatement
ExpressionStatement
ContinueStatement
BreakStatement
ThrowStatement
DebuggerStatement
Block :
{
}
ReturnStatement :
return
;
LabelledItem :
FunctionDeclaration
ForInOfStatement :
for
(
LeftHandSideExpression
of
AssignmentExpression
)
Statement
for
(
var
ForBinding
of
AssignmentExpression
)
Statement
for
(
ForDeclaration
of
AssignmentExpression
)
Statement
CaseBlock :
{
}
返回 false 。
IfStatement :
if
(
Expression
)
Statement
else
Statement
令 has 为第一个 Statement 以参数 call 进行的 HasCallInTailPosition 。
如果 has 是 true ,返回 true 。
返回第二个 Statement 以参数
call 进行的 HasCallInTailPosition 。
IfStatement :
if
(
Expression
)
Statement
DoWhileStatement :
do
Statement
while
(
Expression
)
;
WhileStatement :
while
(
Expression
)
Statement
ForStatement :
for
(
Expression opt
;
Expression opt
;
Expression opt
)
Statement
for
(
var
VariableDeclarationList
;
Expression opt
;
Expression opt
)
Statement
for
(
LexicalDeclaration
Expression opt
;
Expression opt
)
Statement
ForInOfStatement :
for
(
LeftHandSideExpression
in
Expression
)
Statement
for
(
var
ForBinding
in
Expression
)
Statement
for
(
ForDeclaration
in
Expression
)
Statement
WithStatement :
with
(
Expression
)
Statement
返回 Statement 以参数
call 进行的 HasCallInTailPosition 。
LabelledStatement
:
LabelIdentifier
:
LabelledItem
返回 LabelledItem 以参数
call 进行的 HasCallInTailPosition 。
ReturnStatement :
return
Expression
;
返回 Expression 以参数
call 进行的 HasCallInTailPosition 。
SwitchStatement :
switch
(
Expression
)
CaseBlock
返回 CaseBlock 以参数
call 进行的 HasCallInTailPosition 。
CaseBlock :
{
CaseClauses opt
DefaultClause
CaseClauses opt
}
令 has 为 false 。
如果存在第一个 CaseClauses ,将
has 设置为第一个 CaseClauses 以参数 call 进行的
HasCallInTailPosition 。
如果 has 是 true ,返回 true 。
将 has 设置为 DefaultClause 以参数 call 进行的
HasCallInTailPosition 。
如果 has 是 true ,返回 true 。
如果存在第二个 CaseClauses ,将
has 设置为第二个 CaseClauses 以参数 call 进行的
HasCallInTailPosition 。
返回 has 。
CaseClauses :
CaseClauses
CaseClause
令 has 为 CaseClauses 以参数 call 进行的
HasCallInTailPosition 。
如果 has 是 true ,返回 true 。
返回 CaseClause 以参数
call 进行的 HasCallInTailPosition 。
CaseClause :
case
Expression
:
StatementList opt
DefaultClause :
default
:
StatementList opt
如果存在 StatementList ,返回
StatementList 以参数
call 进行的 HasCallInTailPosition 。
返回 false 。
TryStatement :
try
Block
Catch
返回 Catch 以参数 call
进行的 HasCallInTailPosition 。
TryStatement :
try
Block
Finally
try
Block
Catch
Finally
返回 Finally 以参数
call 进行的 HasCallInTailPosition 。
Catch :
catch
(
CatchParameter
)
Block
返回 Block 以参数 call
进行的 HasCallInTailPosition 。
AssignmentExpression
:
YieldExpression
ArrowFunction
AsyncArrowFunction
LeftHandSideExpression
=
AssignmentExpression
LeftHandSideExpression
AssignmentOperator
AssignmentExpression
LeftHandSideExpression
&&=
AssignmentExpression
LeftHandSideExpression
||=
AssignmentExpression
LeftHandSideExpression
??=
AssignmentExpression
BitwiseANDExpression
:
BitwiseANDExpression
&
EqualityExpression
BitwiseXORExpression
:
BitwiseXORExpression
^
BitwiseANDExpression
BitwiseORExpression
:
BitwiseORExpression
|
BitwiseXORExpression
EqualityExpression
:
EqualityExpression
==
RelationalExpression
EqualityExpression
!=
RelationalExpression
EqualityExpression
===
RelationalExpression
EqualityExpression
!==
RelationalExpression
RelationalExpression
:
RelationalExpression
<
ShiftExpression
RelationalExpression
>
ShiftExpression
RelationalExpression
<=
ShiftExpression
RelationalExpression
>=
ShiftExpression
RelationalExpression
instanceof
ShiftExpression
RelationalExpression
in
ShiftExpression
PrivateIdentifier
in
ShiftExpression
ShiftExpression :
ShiftExpression
<<
AdditiveExpression
ShiftExpression
>>
AdditiveExpression
ShiftExpression
>>>
AdditiveExpression
AdditiveExpression
:
AdditiveExpression
+
MultiplicativeExpression
AdditiveExpression
-
MultiplicativeExpression
MultiplicativeExpression
:
MultiplicativeExpression
MultiplicativeOperator
ExponentiationExpression
ExponentiationExpression
:
UpdateExpression
**
ExponentiationExpression
UpdateExpression :
LeftHandSideExpression
++
LeftHandSideExpression
--
++
UnaryExpression
--
UnaryExpression
UnaryExpression :
delete
UnaryExpression
void
UnaryExpression
typeof
UnaryExpression
+
UnaryExpression
-
UnaryExpression
~
UnaryExpression
!
UnaryExpression
AwaitExpression
CallExpression :
SuperCall
ImportCall
CallExpression
[
Expression
]
CallExpression
.
IdentifierName
CallExpression
.
PrivateIdentifier
NewExpression :
new
NewExpression
MemberExpression :
MemberExpression
[
Expression
]
MemberExpression
.
IdentifierName
SuperProperty
MetaProperty
new
MemberExpression
Arguments
MemberExpression
.
PrivateIdentifier
PrimaryExpression
:
this
IdentifierReference
Literal
ArrayLiteral
ObjectLiteral
FunctionExpression
ClassExpression
GeneratorExpression
AsyncFunctionExpression
AsyncGeneratorExpression
RegularExpressionLiteral
TemplateLiteral
返回 false 。
Expression :
AssignmentExpression
Expression
,
AssignmentExpression
返回 AssignmentExpression 以参数
call 进行的 HasCallInTailPosition 。
ConditionalExpression
:
ShortCircuitExpression
?
AssignmentExpression
:
AssignmentExpression
令 has 为第一个 AssignmentExpression 以参数
call 进行的 HasCallInTailPosition 。
如果 has 是 true ,返回 true 。
返回第二个 AssignmentExpression 以参数
call 进行的 HasCallInTailPosition 。
LogicalANDExpression
:
LogicalANDExpression
&&
BitwiseORExpression
返回 BitwiseORExpression 以参数
call 进行的 HasCallInTailPosition 。
LogicalORExpression
:
LogicalORExpression
||
LogicalANDExpression
返回 LogicalANDExpression 以参数
call 进行的 HasCallInTailPosition 。
CoalesceExpression
:
CoalesceExpressionHead
??
BitwiseORExpression
返回 BitwiseORExpression 以参数
call 进行的 HasCallInTailPosition 。
CallExpression :
CoverCallExpressionAndAsyncArrowHead
CallExpression
Arguments
CallExpression
TemplateLiteral
如果此 CallExpression 是
call ,返回 true 。
返回 false 。
OptionalExpression
:
MemberExpression
OptionalChain
CallExpression
OptionalChain
OptionalExpression
OptionalChain
返回 OptionalChain 以参数
call 进行的 HasCallInTailPosition 。
OptionalChain :
?.
[
Expression
]
?.
IdentifierName
?.
PrivateIdentifier
OptionalChain
[
Expression
]
OptionalChain
.
IdentifierName
OptionalChain
.
PrivateIdentifier
返回 false 。
OptionalChain :
?.
Arguments
OptionalChain
Arguments
如果此 OptionalChain 是
call ,返回 true 。
返回 false 。
MemberExpression :
MemberExpression
TemplateLiteral
如果此 MemberExpression 是 call ,返回
true 。
返回 false 。
PrimaryExpression
: CoverParenthesizedExpressionAndArrowParameterList
令 expr 为被 CoverParenthesizedExpressionAndArrowParameterList
覆盖 的 ParenthesizedExpression 。
返回 expr 以参数 call 进行的 HasCallInTailPosition 。
ParenthesizedExpression
:
(
Expression
)
返回 Expression 以参数
call 进行的 HasCallInTailPosition 。
15.10.3 PrepareForTailCall ( )
抽象操作 PrepareForTailCall 不接受参数,返回 unused 。调用时执行以下步骤:
断言 :当前 执行上下文 随后不会用于任何 ECMAScript
代码或内置函数的求值。在调用此抽象操作之后对 Call 的调用将在执行任何此类求值之前创建并推入一个新的 执行上下文 。
丢弃与当前 执行上下文 关联的所有资源。
返回 unused 。
尾位置调用必须在调用目标函数之前释放与当前执行函数 执行上下文 关联的任何瞬态内部资源,或重用这些资源来支持目标函数。
注释
例如,尾位置调用应该仅按目标函数的激活记录大小超出调用函数激活记录大小的量来增长实现的激活记录栈。如果目标函数的激活记录更小,则栈的总大小应该减少。
16 ECMAScript 语言:脚本和模块
16.1 脚本
语法
Script :
ScriptBody opt
ScriptBody :
StatementList [~Yield, ~Await,
~Return]
16.1.1 静态语义:早期错误
Script : ScriptBody
ScriptBody : StatementList
16.1.2 静态语义:ScriptIsStrict
语法制导操作
ScriptIsStrict 不接受参数,返回一个 Boolean。它按以下产生式分段定义:
Script : ScriptBody opt
如果 ScriptBody 存在且
ScriptBody 的 指令序言 包含一个 Use
Strict 指令 ,返回 true ;否则,返回
false 。
16.1.3 运行时语义:Evaluation
Script : [empty]
返回 undefined 。
16.1.4 脚本记录
脚本记录 封装了关于被求值脚本的信息。每个脚本记录包含
表
39 中列出的字段。
表 39:脚本记录 字段
16.1.5 ParseScript ( sourceText , realm ,
hostDefined )
抽象操作 ParseScript 接受参数 sourceText (ECMAScript 源文本 )、realm (一个 Realm Record )和
hostDefined (任何东西),返回一个 脚本记录 或一个非空的 SyntaxError 对象
List 。它基于将
sourceText 解析为 Script
的结果创建一个 脚本记录 。调用时执行以下步骤:
令 script 为 ParseText (sourceText , Script )。
如果 script 是一个错误的 List ,返回
script 。
返回 脚本记录 { [[Realm]] :
realm ,
[[ECMAScriptCode]] : script , [[LoadedModules]] : « », [[HostDefined]] : hostDefined }。
注释
实现可以在对该脚本源文本执行 ParseScript 之前解析脚本源文本并分析其早期错误条件。但是,任何错误的报告必须推迟到本规范实际对该源文本执行 ParseScript
的时候。
16.1.6 ScriptEvaluation ( scriptRecord )
抽象操作 ScriptEvaluation 接受参数 scriptRecord (一个 脚本记录 ),返回包含一个 ECMAScript 语言值 的 正常完成 或一个 突然完成 。调用时执行以下步骤:
令 globalEnv 为 scriptRecord .[[Realm]] .[[GlobalEnv]] 。
令 scriptContext 为一个新的 ECMAScript
代码执行上下文 。
设置 scriptContext 的 Function 为 null 。
设置 scriptContext 的 Realm 为 scriptRecord .[[Realm]] 。
设置 scriptContext 的 ScriptOrModule 为 scriptRecord 。
设置 scriptContext 的 VariableEnvironment 为 globalEnv 。
设置 scriptContext 的 LexicalEnvironment 为 globalEnv 。
设置 scriptContext 的 PrivateEnvironment 为 null 。
挂起 正在运行的执行上下文 。
将 scriptContext 推入 执行上下文栈 ;scriptContext
现在是 正在运行的执行上下文 。
令 script 为 scriptRecord .[[ECMAScriptCode]] 。
令 result 为 Completion (GlobalDeclarationInstantiation (script ,
globalEnv ))。
如果 result 是一个 正常完成 ,则
设置 result 为 Completion (script 的
Evaluation )。
如果 result 是一个 正常完成 且
result .[[Value]] 是
empty ,则
设置 result 为 NormalCompletion (undefined )。
挂起 scriptContext 并将其从 执行上下文栈 中移除。
断言 :执行上下文栈 不为空。
恢复现在位于 执行上下文栈 顶部的上下文作为 正在运行的执行上下文 。
返回 ? result 。
16.1.7 GlobalDeclarationInstantiation ( script ,
env )
抽象操作 GlobalDeclarationInstantiation 接受参数 script (一个 Script 解析节点 )和 env (一个
全局环境记录 ),返回包含
unused 的 正常完成 或一个
抛出完成 。script
是正在为其建立 执行上下文 的 Script 。env 是要在其中创建绑定的全局环境。
注释 1
当为求值脚本建立 执行上下文
时,声明在当前全局环境中实例化。代码中声明的每个全局绑定都被实例化。
调用时执行以下步骤:
令 lexNames 为 script 的 LexicallyDeclaredNames 。
令 varNames 为 script 的 VarDeclaredNames 。
对于 lexNames 的每个元素 name ,执行
如果 HasLexicalDeclaration (env ,
name ) 是 true ,抛出一个 SyntaxError
异常。
令 hasRestrictedGlobal 为 ? HasRestrictedGlobalProperty (env ,
name )。
注释:全局 var 和 function 绑定(除了由非严格 直接
eval 引入的那些)是不可配置的,因此是受限制的全局属性。
如果 hasRestrictedGlobal 是 true ,抛出一个
SyntaxError 异常。
对于 varNames 的每个元素 name ,执行
如果 HasLexicalDeclaration (env ,
name ) 是 true ,抛出一个 SyntaxError
异常。
令 varDeclarations 为 script 的 VarScopedDeclarations 。
令 functionsToInitialize 为一个新的空 List 。
令 declaredFunctionNames 为一个新的空 List 。
对于 varDeclarations 的每个元素 d ,按反向 List 顺序,执行
如果 d 不是 VariableDeclaration 、ForBinding 或 BindingIdentifier ,则
断言 :d 是 FunctionDeclaration 、GeneratorDeclaration 、AsyncFunctionDeclaration
或 AsyncGeneratorDeclaration 。
注释:如果同一个名称有多个函数声明,使用最后的声明。
令 fn 为 d 的 BoundNames
的唯一元素。
如果 declaredFunctionNames 不包含 fn ,则
令 fnDefinable 为 ? CanDeclareGlobalFunction (env ,
fn )。
如果 fnDefinable 是 false ,抛出一个
TypeError 异常。
将 fn 追加到 declaredFunctionNames 。
将 d 作为 functionsToInitialize 的第一个元素插入。
令 declaredVarNames 为一个新的空 List 。
对于 varDeclarations 的每个元素 d ,执行
如果 d 是 VariableDeclaration 、ForBinding 或 BindingIdentifier ,则
对于 d 的 BoundNames
的每个字符串 vn ,执行
如果 declaredFunctionNames 不包含 vn ,则
令 vnDefinable 为 ? CanDeclareGlobalVar (env ,
vn )。
如果 vnDefinable 是
false ,抛出一个
TypeError 异常。
如果 declaredVarNames 不包含 vn ,则
将 vn 追加到 declaredVarNames 。
注释:如果 全局对象 是一个 普通对象 ,则在此算法步骤之后不会发生异常终止。但是,如果 全局对象 是一个 Proxy
异质对象 ,它可能表现出在以下某些步骤中导致异常终止的行为。
注释:附录 B.3.2.2
在此处添加了附加步骤。
令 lexDeclarations 为 script 的 LexicallyScopedDeclarations 。
令 privateEnv 为 null 。
对于 lexDeclarations 的每个元素 d ,执行
注释:词法声明的名称仅在此处实例化但不初始化。
对于 d 的 BoundNames 的每个元素
dn ,执行
如果 d 的 IsConstantDeclaration
是 true ,则
执行 ? env .CreateImmutableBinding (dn ,
true )。
否则,
执行 ? env .CreateMutableBinding (dn ,
false )。
对于 functionsToInitialize 的每个 解析节点 f ,执行
令 fn 为 f 的 BoundNames 的唯一元素。
令 fo 为 f 以参数 env 和 privateEnv 进行的
InstantiateFunctionObject 。
执行 ? CreateGlobalFunctionBinding (env ,
fn , fo , false )。
对于 declaredVarNames 的每个字符串 vn ,执行
执行 ? CreateGlobalVarBinding (env ,
vn , false )。
返回 unused 。
注释 2
16.1.1 中指定的
早期错误
防止了函数/var 声明与 let/const/class 声明之间的名称冲突,以及单个 Script 内包含的声明的 let/const/class
绑定的重新声明。但是,这种跨越多个 Script
的冲突和重新声明在 GlobalDeclarationInstantiation 期间被检测为运行时错误。如果检测到任何此类错误,则不会为脚本实例化绑定。但是,如果
全局对象 使用 Proxy
异质对象 定义,则冲突声明的运行时测试可能不可靠,导致 突然完成
和一些全局声明未被实例化。如果发生这种情况,Script
的代码不会被求值。
与显式的 var 或 function 声明不同,直接在 全局对象 上创建的属性会导致可能被 let/const/class
声明遮蔽的全局绑定。
16.2 模块
语法
Module :
ModuleBody opt
ModuleBody :
ModuleItemList
ModuleItemList :
ModuleItem
ModuleItemList
ModuleItem
ModuleItem :
ImportDeclaration
ExportDeclaration
StatementListItem [~Yield,
+Await, ~Return]
ModuleExportName :
IdentifierName
StringLiteral
16.2.1 模块语义
16.2.1.1 静态语义:早期错误
ModuleBody : ModuleItemList
注
重复 ExportedNames 规则
意味着在 ModuleBody
中包含多个 export default ExportDeclaration 项是语法错误。在
Module
求值之前的模块链接期间检查与冲突或重复声明相关的其他错误条件。如果检测到任何此类错误,则不会对 Module 进行求值。
ModuleExportName
: StringLiteral
16.2.1.2 静态语义:ImportedLocalNames (
importEntries )
抽象操作 ImportedLocalNames 接受参数 importEntries (一个
List of ImportEntry
Records )并返回一个字符串的 List 。它创建一个包含所有由
importEntries 定义的本地名称绑定的 List 。调用时它执行以下步骤:
让 localNames 为一个新的空 List 。
对于 importEntries 的每个 ImportEntry Record
i ,执行
将 i .[[LocalName]] 追加到
localNames 。
返回 localNames 。
16.2.1.3 ModuleRequest 记录
ModuleRequest
Record 表示带有给定导入属性的模块导入请求。它由以下字段组成:
表 40:ModuleRequest Record 字段
LoadedModuleRequest Record 表示模块导入请求以及结果 Module Record 。它由表 表
40 中定义的相同字段组成,并添加了
[[Module]] :
表 41:LoadedModuleRequest Record
字段
ImportAttribute Record 由以下字段组成:
表 42:ImportAttribute Record 字段
字段名称
值类型
含义
[[Key]]
一个字符串
属性键
[[Value]]
一个字符串
属性值
16.2.1.3.1 ModuleRequestsEqual ( left ,
right )
抽象操作 ModuleRequestsEqual 接受参数 left (一个 ModuleRequest Record
或一个 LoadedModuleRequest Record )
和 right (一个 ModuleRequest Record 或一个 LoadedModuleRequest Record )
并返回一个布尔值。调用时它执行以下步骤:
如果 left .[[Specifier]] 不是
right .[[Specifier]] ,返回
false 。
让 leftAttrs 为 left .[[Attributes]] 。
让 rightAttrs 为 right .[[Attributes]] 。
让 leftAttrsCount 为 leftAttrs 中元素的数量。
让 rightAttrsCount 为 rightAttrs 中元素的数量。
如果 leftAttrsCount ≠ rightAttrsCount ,返回
false 。
对于 leftAttrs 的每个 ImportAttribute
Record
l ,执行
如果 rightAttrs 不包含一个 ImportAttribute
Record r 使得 l .[[Key]] 是 r .[[Key]] 且 l .[[Value]] 是 r .[[Value]] ,返回 false 。
返回 true 。
16.2.1.4 静态语义:ModuleRequests
语法导向操作
ModuleRequests 不接受参数并返回一个 List of
ModuleRequest Records 。它对以下产生式逐段定义:
Module : [empty]
返回一个新的空 List 。
ModuleItemList :
ModuleItem
返回 ModuleItem 的
ModuleRequests 。
ModuleItemList :
ModuleItemList
ModuleItem
让 requests 为 ModuleItemList 的 ModuleRequests 。
让 additionalRequests 为 ModuleItem 的 ModuleRequests 。
对于 additionalRequests 的每个 ModuleRequest
Record
mr ,执行
如果 requests 不包含一个 ModuleRequest
Record
mr2 使得 ModuleRequestsEqual (mr ,
mr2 ) 是 true ,那么
将 mr 追加到 requests 。
返回 requests 。
ModuleItem : StatementListItem
返回一个新的空 List 。
ImportDeclaration
:
import
ImportClause
FromClause
;
让 specifier 为 FromClause 的 SV 。
返回一个 List ,其唯一元素是
ModuleRequest Record { [[Specifier]] : specifier , [[Attributes]] : « » }。
ImportDeclaration
:
import
ImportClause
FromClause
WithClause
;
让 specifier 为 FromClause 的 SV 。
让 attributes 为 WithClause 的 WithClauseToAttributes 。
返回一个 List ,其唯一元素是
ModuleRequest Record { [[Specifier]] : specifier , [[Attributes]] : attributes }。
ImportDeclaration
:
import
ModuleSpecifier
;
让 specifier 为 ModuleSpecifier 的 SV 。
返回一个 List ,其唯一元素是
ModuleRequest Record { [[Specifier]] : specifier , [[Attributes]] : « » }。
ImportDeclaration
:
import
ModuleSpecifier
WithClause
;
让 specifier 为 ModuleSpecifier 的 SV 。
让 attributes 为 WithClause 的 WithClauseToAttributes 。
返回一个 List ,其唯一元素是
ModuleRequest Record { [[Specifier]] : specifier , [[Attributes]] : attributes }。
ExportDeclaration
:
export
ExportFromClause
FromClause
;
让 specifier 为 FromClause 的 SV 。
返回一个 List ,其唯一元素是
ModuleRequest Record { [[Specifier]] : specifier , [[Attributes]] : « » }。
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause
;
让 specifier 为 FromClause 的 SV 。
让 attributes 为 WithClause 的 WithClauseToAttributes 。
返回一个 List ,其唯一元素是
ModuleRequest Record { [[Specifier]] : specifier , [[Attributes]] : attributes }。
ExportDeclaration
:
export
NamedExports
;
export
VariableStatement
export
Declaration
export
default
HoistableDeclaration
export
default
ClassDeclaration
export
default
AssignmentExpression
;
返回一个新的空 List 。
16.2.1.5 抽象模块记录
Module Record
封装了单个模块的导入和导出的结构信息。此信息用于链接连接模块集合的导入和导出。Module Record 包含四个仅在求值模块时使用的字段。
出于规范目的,Module Record 值是 Record
规范类型的值,可以认为存在于一个简单的面向对象层次结构中,其中 Module
Record 是一个抽象类,具有抽象和具体子类。本规范定义了名为 Cyclic Module Record 的抽象子类及其名为 Source
Text Module Record 的具体子类。其他规范和实现可以定义对应于它们定义的替代模块定义设施的额外 Module Record
子类。
Module Record 定义了 表 43 中列出的字段。所有 Module
Definition 子类至少包含这些字段。Module Record 还定义了 表 44 中的抽象方法列表。所有
Module
definition 子类必须提供这些抽象方法的具体实现。
表 43:Module Record 字段
表 44:Module
Records 的抽象方法
方法
目的
LoadRequestedModules([hostDefined ])
通过递归加载所有依赖项为链接准备模块,并返回一个 promise。
GetExportedNames([exportStarSet ])
返回从此模块直接或间接导出的所有名称的列表。
在调用此方法之前,LoadRequestedModules 必须已成功完成。
ResolveExport(exportName [, resolveSet ])
返回此模块导出的名称的绑定。绑定由 ResolvedBinding
Record 表示,形式为 { [[Module]] :
Module
Record , [[BindingName]] : String |
namespace }。如果导出是没有任何模块中直接绑定的模块命名空间对象,[[BindingName]] 将设置为
namespace 。如果名称无法解析,返回
null ,如果找到多个绑定,返回
ambiguous 。
每次使用特定的 exportName 、resolveSet
对作为参数调用此操作时,必须返回相同的结果。
在调用此方法之前,LoadRequestedModules 必须已成功完成。
Link()
通过传递性地解析所有模块依赖项并创建 Module
Environment
Record 为求值准备模块。
在调用此方法之前,LoadRequestedModules 必须已成功完成。
Evaluate()
返回用于此模块及其依赖项求值的 promise,在成功求值或已成功求值时解析,在求值错误或已求值失败时拒绝。如果 promise
被拒绝,期望 宿主 处理 promise 拒绝并重新抛出求值错误。
在调用此方法之前,Link 必须已成功完成。
16.2.1.5.1 EvaluateModuleSync ( module )
抽象操作 EvaluateModuleSync 接受参数 module (一个 Module Record )并返回
一个 正常完成,包含
unused 或一个 抛出完成 。它同步求值
module ,前提是调用者保证 module 的求值将返回一个已经结算的 promise。调用时它执行以下步骤:
断言 :
module 不是 Cyclic Module
Record 。
让 promise 为 module .Evaluate()。
断言 :
promise .[[PromiseState]] 是
fulfilled 或 rejected 。
如果 promise .[[PromiseState]] 是
rejected ,那么
如果 promise .[[PromiseIsHandled]] 是
false ,执行 HostPromiseRejectionTracker (promise ,
"handle" )。
设置 promise .[[PromiseIsHandled]] 为
true 。
返回 ThrowCompletion (promise .[[PromiseResult]] )。
返回 unused 。
16.2.1.6 循环模块记录
Cyclic Module
Record 用于表示可以与 Cyclic
Module Record 类型的子类的其他模块参与依赖循环的模块的信息。不是 Cyclic
Module Record 类型的子类的 Module Records 不得与
Source Text Module
Records 参与依赖循环。
除了 表 43 中定义的字段外,Cyclic
Module Records 还具有 表 45 中列出的附加字段
表 45:Cyclic Module
Records 的附加字段
字段名称
值类型
含义
[[Status]]
new 、unlinked 、
linking 、linked 、
evaluating 、
evaluating-async 或
evaluated
初始为 new 。随着模块在其生命周期中的进展,按顺序转换为
unlinked 、linking 、
linked 、evaluating 、
可能是 evaluating-async 、
evaluated 。
evaluating-async 表示此模块排队等待在其异步依赖完成时执行,或者它是一个
[[HasTLA]] 字段为
true 的模块,已执行并等待顶级完成。
[[EvaluationError]]
一个 抛出完成
或 empty
表示求值期间发生的异常的 抛出完成 。如果没有发生异常或
[[Status]] 不是
evaluated ,则为 undefined 。
[[DFSIndex]]
一个 整数 或
empty
仅在 Link 和 Evaluate 期间使用的辅助字段。如果 [[Status]] 是
linking 或 evaluating ,
此非负数记录模块在依赖图的深度优先遍历中首次访问的点。
[[DFSAncestorIndex]]
一个 整数 或
empty
仅在 Link 和 Evaluate 期间使用的辅助字段。如果 [[Status]] 是
linking 或 evaluating ,
这是模块自己的 [[DFSIndex]] 或同一强连通分量中"较早"模块的该值。
[[RequestedModules]]
ModuleRequest
Records 的 List
与此模块中的导入关联的 ModuleRequest
Records 的 List 。该
List
按导入的源文本出现顺序排列。
[[LoadedModules]]
LoadedModuleRequest
Records 的 List
从此记录表示的模块用于请求导入具有相对导入属性的模块的说明符字符串到已解析的 Module
Record 的映射。该列表不包含两个不同的 Records
r1 和 r2 ,使得 ModuleRequestsEqual (r1 ,
r2 ) 为 true 。
[[CycleRoot]]
一个 Cyclic Module Record
或 empty
循环的第一个访问模块,强连通分量的根 DFS 祖先。对于不在循环中的模块,这将是模块本身。一旦 Evaluate 完成,模块的 [[DFSAncestorIndex]] 是其 [[CycleRoot]] 的 [[DFSIndex]] 。
[[HasTLA]]
一个布尔值
此模块是否单独异步(例如,如果它是包含顶级等待的 Source Text Module
Record )。具有异步依赖项并不意味着此字段为
true 。此字段在模块解析后不得更改。
[[AsyncEvaluationOrder]]
unset 、一个 整数 或
done
此字段初始设置为 unset ,对于完全同步的模块保持
unset 。对于自身异步或具有异步依赖项的模块,它设置为一个 整数 ,该整数确定 16.2.1.6.1.3.4
排队执行待处理模块的顺序。
一旦待处理模块被执行,该字段设置为
done 。
[[TopLevelCapability]]
一个 PromiseCapability
Record 或 empty
如果此模块是某个循环的 [[CycleRoot]] ,并且在该循环中的某个模块上调用了
Evaluate(),此字段包含该整个求值的 PromiseCapability
Record 。它用于解决从 Evaluate() 抽象方法返回的 Promise
对象。除非为这些依赖项中的某些启动了顶级 Evaluate(),否则该字段对于该模块的任何依赖项都将是
empty 。
[[AsyncParentModules]]
Cyclic Module
Records 的 List
如果此模块或依赖项的 [[HasTLA]] 为
true ,并且执行正在进行中,这会跟踪此模块的顶级执行作业的父导入器。这些父模块在此模块成功完成执行之前不会开始执行。
[[PendingAsyncDependencies]]
一个 整数 或
empty
如果此模块有任何异步依赖项,这会跟踪此模块剩余要执行的异步依赖模块数量。
当此字段达到 0 且没有执行错误时,具有异步依赖项的模块将被执行。
除了 表 44
中定义的方法外,Cyclic
Module Records 还具有 表 46 中列出的附加方法
表 46:Cyclic Module Records 的附加抽象方法
GraphLoadingState Record 是一个 Record ,包含有关模块图加载过程的信息。它用于在调用
HostLoadImportedModule 后继续加载。每个
GraphLoadingState Record 都有
表 47 中定义的字段:
表 47:GraphLoadingState Record
字段
16.2.1.6.1 Module Record 抽象方法的实现
以下是 Cyclic Module Record
的具体方法,它们实现了 表
44 中定义的相应 Module Record
抽象方法。
16.2.1.6.1.1 LoadRequestedModules ( [
hostDefined ] )
Cyclic Module
Record module 的 LoadRequestedModules 具体方法接受可选参数
hostDefined (任何内容)并返回一个 Promise。它填充 module 依赖图中所有 Module Records 的 [[LoadedModules]] (大部分工作由辅助函数 InnerModuleLoading
完成)。它接受一个可选的 hostDefined 参数,该参数传递给 HostLoadImportedModule
钩子。调用时执行以下步骤:
如果 hostDefined 不存在,让 hostDefined 为
empty 。
让 pc 为 ! NewPromiseCapability (%Promise% )。
让 state 为 GraphLoadingState
Record { [[IsLoading]] :
true ,[[PendingModulesCount]] :
1,[[Visited]] : « »,[[PromiseCapability]] : pc ,[[HostDefined]] : hostDefined }。
执行 InnerModuleLoading (state ,
module )。
返回 pc .[[Promise]] 。
注意
hostDefined 参数可用于传递获取导入模块所需的附加信息。例如,HTML 使用它为
<link rel="preload" as="..."> 标签设置正确的 fetch 目标。
import() 表达式从不设置 hostDefined
参数。
16.2.1.6.1.1.1 InnerModuleLoading (
state , module )
抽象操作 InnerModuleLoading 接受参数 state (一个
GraphLoadingState
Record )和 module (一个 Module Record )并返回
unused 。它被 LoadRequestedModules 用于递归执行 module
依赖图的实际加载过程。调用时执行以下步骤:
断言 :state .[[IsLoading]] 是 true 。
如果 module 是 Cyclic Module
Record ,module .[[Status]] 是 new ,并且
state .[[Visited]] 不包含
module ,那么
将 module 追加到 state .[[Visited]] 。
让 requestedModulesCount 为 module .[[RequestedModules]] 中的元素数量。
设置 state .[[PendingModulesCount]] 为
state .[[PendingModulesCount]] +
requestedModulesCount 。
对于 module .[[RequestedModules]] 的每个 ModuleRequest
Record request ,执行
如果 AllImportAttributesSupported (request .[[Attributes]] ) 是
false ,那么
让 error 为 ThrowCompletion (一个新创建的
SyntaxError
对象)。
执行 ContinueModuleLoading (state ,
error )。
否则,如果 module .[[LoadedModules]] 包含一个 LoadedModuleRequest
Record record ,使得
ModuleRequestsEqual (record ,
request ) 是 true ,那么
执行 InnerModuleLoading (state ,
record .[[Module]] )。
否则,
执行 HostLoadImportedModule (module ,
request , state .[[HostDefined]] ,
state )。
注意:HostLoadImportedModule
将调用 FinishLoadingImportedModule ,
它通过 ContinueModuleLoading
重新进入图加载过程。
如果 state .[[IsLoading]] 是
false ,返回
unused 。
断言 :state .[[PendingModulesCount]] ≥ 1。
设置 state .[[PendingModulesCount]] 为
state .[[PendingModulesCount]] - 1。
如果 state .[[PendingModulesCount]] =
0,那么
设置 state .[[IsLoading]] 为
false 。
对于 state .[[Visited]] 的每个
Cyclic Module
Record loaded ,执行
如果 loaded .[[Status]]
是 new ,设置
loaded .[[Status]] 为
unlinked 。
执行 ! Call (state .[[PromiseCapability]] .[[Resolve]] ,
undefined , «
undefined »)。
返回 unused 。
16.2.1.6.1.1.2 ContinueModuleLoading (
state , moduleCompletion )
抽象操作 ContinueModuleLoading 接受参数 state (一个
GraphLoadingState
Record )和 moduleCompletion (一个 包含
Module Record 的
正常完成 或一个
抛出
完成 )并返回 unused 。它用于在调用 HostLoadImportedModule
后重新进入加载过程。
调用时执行以下步骤:
如果 state .[[IsLoading]] 是
false ,返回 unused 。
如果 moduleCompletion 是 正常
完成 ,那么
执行 InnerModuleLoading (state ,
moduleCompletion .[[Value]] )。
否则,
设置 state .[[IsLoading]] 为
false 。
执行 ! Call (state .[[PromiseCapability]] .[[Reject]] ,
undefined , « moduleCompletion .[[Value]] »)。
返回 unused 。
16.2.1.6.1.2 Link ( )
Cyclic Module
Record module 的 Link 具体方法不接受参数,并返回一个 包含
unused 的 正常
完成 或一个 抛出
完成 。成功时,Link 将此模块的 [[Status]] 从
unlinked 转换为
linked 。失败时,抛出异常并且此模块的
[[Status]] 保持为 unlinked 。(大部分工作由辅助函数
InnerModuleLinking
完成。)调用时执行以下步骤:
断言 :module .[[Status]] 是
unlinked 、linked 、
evaluating-async 或
evaluated 之一。
让 stack 为一个新的空 List 。
让 result 为 Completion (InnerModuleLinking (module ,
stack , 0))。
如果 result 是 突然完成 ,那么
对于 stack 的每个 Cyclic Module
Record m ,执行
断言 :
m .[[Status]] 是
linking 。
设置 m .[[Status]] 为
unlinked 。
断言 :module .[[Status]] 是
unlinked 。
返回 ? result 。
断言 :module .[[Status]] 是 linked 、
evaluating-async 或
evaluated 之一。
断言 :stack 是空的。
返回 unused 。
16.2.1.6.1.2.1 InnerModuleLinking (
module , stack , index )
抽象操作 InnerModuleLinking 接受参数 module (一个
Module Record )、
stack (Cyclic Module Records 的
List )和
index (一个非负 整数 ),并返回一个 包含 非负
整数 的
正常完成 或一个
抛出
完成 。它被 Link 用于对 module
以及依赖图中的所有其他模块递归执行实际的链接过程。stack 和 index
参数,以及模块的 [[DFSIndex]] 和 [[DFSAncestorIndex]] 字段,跟踪深度优先搜索(DFS)遍历。特别地,[[DFSAncestorIndex]] 用于发现强连通分量(SCC),使得 SCC 中的所有模块一起转换为
linked 。调用时执行以下步骤:
如果 module 不是 Cyclic Module
Record ,那么
执行 ? module .Link()。
返回 index 。
如果 module .[[Status]] 是
linking 、linked 、
evaluating-async 或
evaluated 之一,那么
返回 index 。
断言 :module .[[Status]] 是 unlinked 。
设置 module .[[Status]] 为
linking 。
设置 module .[[DFSIndex]] 为
index 。
设置 module .[[DFSAncestorIndex]] 为
index 。
设置 index 为 index + 1。
将 module 追加到 stack 。
对于 module .[[RequestedModules]] 的每个
ModuleRequest Record
request ,执行
让 requiredModule 为 GetImportedModule (module ,
request )。
设置 index 为 ? InnerModuleLinking (requiredModule ,
stack , index )。
如果 requiredModule 是 Cyclic Module
Record ,那么
断言 :
requiredModule .[[Status]] 是
linking 、
linked 、
evaluating-async 或
evaluated 之一。
断言 :
requiredModule .[[Status]] 是
linking 当且仅当
stack 包含 requiredModule 。
如果 requiredModule .[[Status]] 是
linking ,那么
设置 module .[[DFSAncestorIndex]] 为
min (module .[[DFSAncestorIndex]] ,
requiredModule .[[DFSAncestorIndex]] )。
执行 ? module .InitializeEnvironment()。
断言 :module 在
stack 中恰好出现一次。
断言 :module .[[DFSAncestorIndex]] ≤ module .[[DFSIndex]] 。
如果 module .[[DFSAncestorIndex]] =
module .[[DFSIndex]] ,那么
让 done 为 false 。
重复,当 done 是 false 时,
让 requiredModule 为 stack 的最后一个元素。
移除 stack 的最后一个元素。
断言 :
requiredModule 是 Cyclic Module
Record 。
设置 requiredModule .[[Status]] 为
linked 。
如果 requiredModule 和 module 是同一个
Module
Record ,设置 done 为
true 。
返回 index 。
16.2.1.6.1.3 Evaluate ( )
Cyclic Module
Record module 的 Evaluate 具体方法不接受参数并返回一个
Promise。Evaluate 将此模块的 [[Status]] 从
linked 转换为 evaluating-async 或
evaluated 。当第一次在给定强连通分量中的模块上调用时,Evaluate 创建并返回一个 Promise,该
Promise 在模块完成求值时解析。此 Promise 存储在该分量的 [[CycleRoot]] 的 [[TopLevelCapability]] 字段中。在该分量中任何模块上后续调用 Evaluate 都会返回相同的
Promise。(大部分工作由辅助函数 InnerModuleEvaluation
完成。)调用时执行以下步骤:
断言 :此次 Evaluate 调用不会与 surrounding agent 内的另一次
Evaluate 调用同时发生。
断言 :module .[[Status]] 是 linked 、
evaluating-async 或
evaluated 之一。
如果 module .[[Status]] 是
evaluating-async 或 evaluated ,
设置 module 为 module .[[CycleRoot]] 。
如果 module .[[TopLevelCapability]] 不是
empty ,那么
返回 module .[[TopLevelCapability]] .[[Promise]] 。
让 stack 为一个新的空 List 。
让 capability 为 ! NewPromiseCapability (%Promise% )。
设置 module .[[TopLevelCapability]] 为
capability 。
让 result 为 Completion (InnerModuleEvaluation (module ,
stack , 0))。
如果 result 是 突然完成 ,那么
对于 stack 的每个 Cyclic Module
Record m ,执行
断言 :
m .[[Status]] 是
evaluating 。
断言 :
m .[[AsyncEvaluationOrder]] 是
unset 。
设置 m .[[Status]] 为
evaluated 。
设置 m .[[EvaluationError]]
为
result 。
断言 :module .[[Status]] 是
evaluated 。
断言 :module .[[EvaluationError]] 和 result
是相同的 Completion
Record 。
执行 ! Call (capability .[[Reject]] , undefined , «
result .[[Value]] »)。
否则,
断言 :module .[[Status]] 是
evaluating-async 或
evaluated 。
断言 :module .[[EvaluationError]] 是
empty 。
如果 module .[[Status]] 是
evaluated ,那么
注意:这意味着 module 的求值同步完成。
断言 :
module .[[AsyncEvaluationOrder]] 是
unset 。
执行 ! Call (capability .[[Resolve]] ,
undefined , «
undefined »)。
断言 :stack 是空的。
返回 capability .[[Promise]] 。
16.2.1.6.1.3.1 InnerModuleEvaluation (
module , stack , index )
抽象操作 InnerModuleEvaluation 接受参数 module (一个
Module Record )、
stack (Cyclic Module Records 的
List )和
index (一个非负 整数 ),并返回一个 包含 非负
整数 的
正常完成 或一个
抛出
完成 。它被 Evaluate 用于对 module
以及依赖图中的所有其他模块递归执行实际的求值过程。stack 和 index
参数,以及 module 的 [[DFSIndex]]
和 [[DFSAncestorIndex]] 字段,其使用方式与 InnerModuleLinking
中相同。调用时执行以下步骤:
如果 module 不是 Cyclic Module
Record ,那么
执行 ? EvaluateModuleSync (module )。
返回 index 。
如果 module .[[Status]] 是
evaluating-async 或
evaluated ,那么
如果 module .[[EvaluationError]] 是
empty ,返回 index 。
否则,返回 ? module .[[EvaluationError]] 。
如果 module .[[Status]] 是
evaluating ,返回 index 。
断言 :module .[[Status]] 是 linked 。
设置 module .[[Status]] 为
evaluating 。
设置 module .[[DFSIndex]] 为
index 。
设置 module .[[DFSAncestorIndex]] 为
index 。
设置 module .[[PendingAsyncDependencies]] 为 0。
设置 index 为 index + 1。
将 module 追加到 stack 。
对于 module .[[RequestedModules]] 的每个
ModuleRequest Record
request ,执行
让 requiredModule 为 GetImportedModule (module ,
request )。
设置 index 为 ? InnerModuleEvaluation (requiredModule ,
stack , index )。
如果 requiredModule 是 Cyclic Module
Record ,那么
断言 :
requiredModule .[[Status]] 是
evaluating 、
evaluating-async 或
evaluated 之一。
断言 :
requiredModule .[[Status]] 是
evaluating 当且仅当
stack 包含 requiredModule 。
如果 requiredModule .[[Status]] 是
evaluating ,那么
设置 module .[[DFSAncestorIndex]] 为
min (module .[[DFSAncestorIndex]] ,
requiredModule .[[DFSAncestorIndex]] )。
否则,
设置 requiredModule 为
requiredModule .[[CycleRoot]] 。
断言 :
requiredModule .[[Status]] 是
evaluating-async 或
evaluated 。
如果 requiredModule .[[EvaluationError]] 不是
empty ,返回
? requiredModule .[[EvaluationError]] 。
如果 requiredModule .[[AsyncEvaluationOrder]] 是
整数 ,那么
设置 module .[[PendingAsyncDependencies]]
为 module .[[PendingAsyncDependencies]]
+ 1。
将 module 追加到
requiredModule .[[AsyncParentModules]] 。
如果 module .[[PendingAsyncDependencies]] > 0 或
module .[[HasTLA]] 是
true ,那么
断言 :
module .[[AsyncEvaluationOrder]] 是
unset 。
设置 module .[[AsyncEvaluationOrder]] 为 IncrementModuleAsyncEvaluationCount ()。
如果 module .[[PendingAsyncDependencies]] = 0,
执行 ExecuteAsyncModule (module )。
否则,
执行 ? module .ExecuteModule() 。
断言 :module 在
stack 中恰好出现一次。
断言 :module .[[DFSAncestorIndex]] ≤ module .[[DFSIndex]] 。
如果 module .[[DFSAncestorIndex]] =
module .[[DFSIndex]] ,那么
让 done 为 false 。
重复,当 done 是 false 时,
让 requiredModule 为 stack 的最后一个元素。
移除 stack 的最后一个元素。
断言 :
requiredModule 是 Cyclic Module
Record 。
断言 :
requiredModule .[[AsyncEvaluationOrder]] 是
整数 或
unset 。
如果 requiredModule .[[AsyncEvaluationOrder]] 是
unset ,设置
requiredModule .[[Status]] 为
evaluated 。
否则,设置 requiredModule .[[Status]] 为
evaluating-async 。
如果 requiredModule 和 module 是同一个
Module
Record ,设置 done 为
true 。
设置 requiredModule .[[CycleRoot]] 为
module 。
返回 index 。
注意 1
模块在被 InnerModuleEvaluation 遍历时处于 evaluating
状态。模块在执行完成时处于 evaluated 状态,或者在执行期间如果其 [[HasTLA]] 字段为
true 或具有异步依赖时处于
evaluating-async 状态。
注意 2
当异步循环不是 evaluating 时,依赖于异步循环模块的任何模块将通过 [[CycleRoot]]
依赖于循环根的执行。这确保循环状态可以通过其根模块状态作为单个强连通分量进行处理。
16.2.1.6.1.3.2 ExecuteAsyncModule (
module )
抽象操作 ExecuteAsyncModule 接受参数 module (一个
Cyclic Module Record )并返回
unused 。调用时执行以下步骤:
断言 :module .[[Status]] 是
evaluating 或
evaluating-async 。
断言 :module .[[HasTLA]] 是 true 。
让 capability 为 ! NewPromiseCapability (%Promise% )。
让 fulfilledClosure 为一个新的 Abstract Closure ,
不接受参数,捕获 module ,并在调用时执行以下步骤:
执行 AsyncModuleExecutionFulfilled (module )。
返回 undefined 。
让 onFulfilled 为 CreateBuiltinFunction (fulfilledClosure ,
0, "" , « »)。
让 rejectedClosure 为一个新的 Abstract Closure ,
接受参数 (error ),捕获 module ,并在调用时执行以下步骤:
执行 AsyncModuleExecutionRejected (module ,
error )。
返回 undefined 。
让 onRejected 为 CreateBuiltinFunction (rejectedClosure ,
0, "" , « »)。
执行 PerformPromiseThen (capability .[[Promise]] , onFulfilled ,
onRejected )。
执行 ! module .ExecuteModule (capability )。
返回 unused 。
16.2.1.6.1.3.3 GatherAvailableAncestors (
module , execList )
抽象操作 GatherAvailableAncestors 接受参数 module
(一个 Cyclic Module Record )和
execList (Cyclic Module Records 的
List )并返回
unused 。调用时执行以下步骤:
对于 module .[[AsyncParentModules]] 的每个
Cyclic Module Record
m ,执行
如果 execList 不包含 m 且
m .[[CycleRoot]] .[[EvaluationError]] 是
empty ,那么
断言 :
m .[[Status]] 是
evaluating-async 。
断言 :
m .[[EvaluationError]] 是
empty 。
断言 :
m .[[AsyncEvaluationOrder]] 是
整数 。
断言 :
m .[[PendingAsyncDependencies]]
> 0。
设置 m .[[PendingAsyncDependencies]] 为
m .[[PendingAsyncDependencies]] -
1。
如果 m .[[PendingAsyncDependencies]] =
0,那么
将 m 追加到 execList 。
如果 m .[[HasTLA]] 是
false ,执行 GatherAvailableAncestors (m ,
execList )。
返回 unused 。
注意
当根 module 的异步执行完成时,此函数确定能够在此完成时同步执行的模块列表,将它们填充到
execList 中。
16.2.1.6.1.3.4 AsyncModuleExecutionFulfilled (
module )
抽象操作 AsyncModuleExecutionFulfilled 接受参数
module (一个 Cyclic Module Record )并返回
unused 。调用时执行以下步骤:
如果 module .[[Status]] 是
evaluated ,那么
断言 :
module .[[EvaluationError]]
不是 empty 。
返回 unused 。
断言 :module .[[Status]] 是
evaluating-async 。
断言 :module .[[AsyncEvaluationOrder]] 是 整数 。
断言 :module .[[EvaluationError]] 是
empty 。
设置 module .[[AsyncEvaluationOrder]]
为 done 。
设置 module .[[Status]] 为
evaluated 。
如果 module .[[TopLevelCapability]] 不是
empty ,那么
断言 :
module .[[CycleRoot]] 和
module 是同一个 Module
Record 。
执行 ! Call (module .[[TopLevelCapability]] .[[Resolve]] ,
undefined , «
undefined »)。
让 execList 为一个新的空 List 。
执行 GatherAvailableAncestors (module ,
execList )。
断言 :execList 的所有元素都将其
[[AsyncEvaluationOrder]] 字段设置为 整数 ,[[PendingAsyncDependencies]] 字段设置为 0,[[EvaluationError]] 字段设置为
empty 。
让 sortedExecList 为一个 List ,
其元素是 execList 的元素,按其
[[AsyncEvaluationOrder]] 字段升序排序。
对于 sortedExecList 的每个 Cyclic Module
Record
m ,执行
如果 m .[[Status]] 是
evaluated ,那么
断言 :
m .[[EvaluationError]] 不是
empty 。
否则,如果 m .[[HasTLA]] 是
true ,那么
执行 ExecuteAsyncModule (m )。
否则,
让 result 为 m .ExecuteModule() 。
如果 result 是 突然完成 ,那么
执行 AsyncModuleExecutionRejected (m ,
result .[[Value]] )。
否则,
设置 m .[[AsyncEvaluationOrder]]
为 done 。
设置 m .[[Status]] 为
evaluated 。
如果 m .[[TopLevelCapability]]
不是 empty ,那么
断言 :
m .[[CycleRoot]]
和 m 是同一个 Module
Record 。
执行 ! Call (m .[[TopLevelCapability]] .[[Resolve]] ,
undefined , «
undefined »)。
返回 unused 。
16.2.1.6.1.3.5 AsyncModuleExecutionRejected (
module , error )
抽象操作 AsyncModuleExecutionRejected 接受参数
module (一个 Cyclic Module Record )和
error (一个 ECMAScript
语言值 )并返回 unused 。调用时执行以下步骤:
如果 module .[[Status]] 是
evaluated ,那么
断言 :
module .[[EvaluationError]]
不是 empty 。
返回 unused 。
断言 :module .[[Status]] 是
evaluating-async 。
断言 :module .[[AsyncEvaluationOrder]] 是 整数 。
断言 :module .[[EvaluationError]] 是
empty 。
设置 module .[[EvaluationError]] 为
ThrowCompletion (error )。
设置 module .[[Status]] 为
evaluated 。
设置 module .[[AsyncEvaluationOrder]]
为 done 。
注意:module .[[AsyncEvaluationOrder]]
设置为
done 是为了与 AsyncModuleExecutionFulfilled
保持对称。
在 InnerModuleEvaluation
中,
当模块的 [[EvaluationError]] 内部槽不是
empty 时,其 [[AsyncEvaluationOrder]] 内部槽的值未被使用。
对于 module .[[AsyncParentModules]] 的每个
Cyclic Module Record
m ,执行
执行 AsyncModuleExecutionRejected (m ,
error )。
如果 module .[[TopLevelCapability]] 不是
empty ,那么
断言 :
module .[[CycleRoot]] 和
module 是同一个 Module
Record 。
执行 ! Call (module .[[TopLevelCapability]] .[[Reject]] ,
undefined , « error »)。
返回 unused 。
16.2.1.6.2 循环模块记录图示例
这个非规范性章节提供了一系列常见模块图链接和求值的示例,特别关注错误如何发生。
首先考虑以下简单的模块图:
图 2:一个简单的模块图
让我们首先假设没有错误条件。当 宿主
首次调用
A .LoadRequestedModules() 时,这将按假设成功完成,并递归加载 B 和 C
的依赖(分别是 C 和无),然后设置 A .[[Status]] =
B .[[Status]] =
C .[[Status]] = unlinked 。
然后,当 宿主
调用 A .Link() 时,它将成功完成(再次按假设),使得
A .[[Status]] = B .[[Status]] = C .[[Status]] =
linked。这些准备步骤可以在任何时候执行。稍后,当 宿主 准备承担模块的任何可能副作用时,它可以调用
A .Evaluate(),这将成功完成,返回一个解析为
undefined 的 Promise(再次按假设),递归地首先求值 C ,然后是
B 。此时每个模块的 [[Status]] 将是
evaluated 。
然后考虑在成功调用 A .LoadRequestedModules() 后涉及链接错误的情况。如果 C 的 InnerModuleLinking
成功,但之后 B 失败,例如因为它导入了 C 不提供的内容,那么原始的
A .Link() 将失败,A 和 B 的 [[Status]] 保持 unlinked 。
不过,C 的 [[Status]] 已变为 linked 。
最后,考虑在成功调用 Link() 后涉及求值错误的情况。如果 C 的 InnerModuleEvaluation
成功,但之后 B 失败,例如因为 B 包含抛出异常的代码,那么原始的
A .Evaluate() 将失败,返回一个被拒绝的 Promise。生成的异常将记录在 A 和 B 的
[[EvaluationError]] 字段中,它们的 [[Status]]
将变为 evaluated 。
C 也将变为 evaluated ,但与 A 和 B
相反,它将保持没有 [[EvaluationError]] ,因为它成功完成了求值。
存储异常确保任何时候 宿主
尝试通过调用它们的 Evaluate() 方法重用 A 或 B 时,它将遇到相同的异常。(宿主 不需要重用 Cyclic
Module Records ;类似地,宿主 不需要暴露这些方法抛出的异常对象。然而,规范启用了这样的用法。)
现在考虑一种不同类型的错误条件:
图 3:具有无法解析模块的模块图
在这种情况下,模块 A 声明对某个其他模块的依赖,但该模块不存在 Module Record ,即
HostLoadImportedModule 在被询问时调用
FinishLoadingImportedModule
时传递异常。这可能由于各种原因发生,例如对应的资源不存在,或者资源存在但 ParseModule 在尝试解析生成的源文本时返回一些错误。宿主 可以选择通过传递给 FinishLoadingImportedModule
的完成来暴露失败原因。
在任何情况下,这个异常导致加载失败,这使得 A 的 [[Status]] 保持
new 。
这里加载、链接和求值错误之间的差异是由于以下特征:
求值
必须只执行一次,因为它可能导致副作用;因此记住求值是否已经执行很重要,即使不成功。(在错误情况下,记住异常也是有意义的,因为否则后续的 Evaluate()
调用将必须合成一个新的异常。)
另一方面,链接是无副作用的,因此即使失败,也可以稍后重试而不会有问题。
加载与 宿主
密切交互,对于其中一些,可能希望允许用户重试失败的加载(例如,如果失败是由临时不良网络条件引起的)。
现在,考虑一个有循环的模块图:
图 4:循环模块图
这里我们假设入口点是模块 A ,因此 宿主 通过调用
A .LoadRequestedModules() 进行,这对 A 执行 InnerModuleLoading 。
这反过来对 B 和 C 调用 InnerModuleLoading 。
由于循环,这再次对 A 触发 InnerModuleLoading ,
但此时它是无操作的,因为 A 的依赖加载已经在这个 LoadRequestedModules 过程中被触发。当图中的所有模块都被成功加载时,它们的
[[Status]] 同时从 new 转换为
unlinked 。
然后 宿主
通过调用 A .Link() 继续,这对 A 执行 InnerModuleLinking 。
这反过来对 B 调用 InnerModuleLinking 。
由于循环,这再次对 A 触发 InnerModuleLinking ,
但此时它是无操作的,因为 A .[[Status]] 已经是
linking 。
当控制回到 A 并且对 C 触发 InnerModuleLinking
时,B .[[Status]] 本身保持 linking 。
在这返回后,C .[[Status]]
是 linked ,A 和 B 一起从
linking 转换为
linked ;这是设计如此,因为它们形成强连通分量。可以同时转换同一 SCC
中模块的状态,因为在这个阶段,模块图通过深度优先搜索遍历。
在成功情况下,循环模块图的求值阶段也发生类似的故事。
现在考虑 A 有链接错误的情况;例如,它尝试从 C 导入一个不存在的绑定。在这种情况下,上述步骤仍然发生,包括从第二次对
A 调用 InnerModuleLinking 的早期返回。
然而,一旦我们展开回到对 A 的原始 InnerModuleLinking ,
它在 InitializeEnvironment 期间失败,即在 C .ResolveExport() 之后立即。抛出的
SyntaxError 异常传播到 A .Link,它重置当前在其 stack
上的所有模块(这些总是正好是仍然 linking 的模块)。因此 A 和 B 都变为
unlinked 。注意 C 保持为 linked 。
或者,考虑 A 有求值错误的情况;例如,它的源代码抛出异常。在这种情况下,上述步骤的求值时类似仍然发生,包括从第二次对 A 调用
InnerModuleEvaluation 的早期返回。
然而,一旦我们展开回到对 A 的原始 InnerModuleEvaluation ,
它按假设失败。抛出的异常传播到 A .Evaluate(),它将错误记录在当前在其 stack 上的所有模块(即仍然
evaluating 的模块)以及通过 [[AsyncParentModules]] 中,这形成了一个链,用于包含或依赖顶层 await
的模块,通过 AsyncModuleExecutionRejected
算法贯穿整个依赖图。因此 A 和 B 都变为 evaluated ,异常记录在
A 和 B 的 [[EvaluationError]] 字段中,而
C
保持为 evaluated ,没有 [[EvaluationError]] 。
最后,考虑一个有循环的模块图,其中所有模块都异步完成:
图 5:异步循环模块图
加载和链接像之前一样发生,所有模块最终的 [[Status]] 设置为
linked 。
调用 A .Evaluate() 对 A 、B 和 D 调用 InnerModuleEvaluation ,
它们都转换为 evaluating 。然后再次对 A 调用 InnerModuleEvaluation ,
这是无操作的,因为它已经是 evaluating 。此时,D .[[PendingAsyncDependencies]] 是 0,因此调用 ExecuteAsyncModule (D ),
我们用一个新的 PromiseCapability 调用 D .ExecuteModule,跟踪 D 的异步执行。我们展开回到对
B 的 InnerModuleEvaluation ,
设置 B .[[PendingAsyncDependencies]]
为 1,B .[[AsyncEvaluationOrder]] 为 1。我们展开回到对
A 的原始 InnerModuleEvaluation ,
设置 A .[[PendingAsyncDependencies]]
为 1。在 A 依赖项循环的下一次迭代中,我们对 C 调用 InnerModuleEvaluation ,
因此对 D (再次无操作)和 E 。由于 E 没有依赖项且不是循环的一部分,我们以与 D
相同的方式调用 ExecuteAsyncModule (E ),
E 立即从堆栈中移除。我们再次展开到对 C 的 InnerModuleEvaluation ,
设置 C .[[AsyncEvaluationOrder]] 为 3。现在我们完成对
A 依赖项的循环,设置 A .[[AsyncEvaluationOrder]] 为
4,并从堆栈中移除整个强连通分量,同时将所有模块转换为 evaluating-async 。此时,模块的字段如 表 48 所示。
表 48:初始 Evaluate() 调用后的模块字段
字段
模块
A
B
C
D
E
[[DFSIndex]]
0
1
3
2
4
[[DFSAncestorIndex]]
0
0
0
0
4
[[Status]]
evaluating-async
evaluating-async
evaluating-async
evaluating-async
evaluating-async
[[AsyncEvaluationOrder]]
4
1
3
0
2
[[AsyncParentModules]]
« »
« A »
« A »
« B , C »
« C »
[[PendingAsyncDependencies]]
2(B 和 C )
1(D )
2(D 和 E )
0
0
让我们假设 E 首先完成执行。当发生这种情况时,调用 AsyncModuleExecutionFulfilled ,
E .[[Status]] 设置为
evaluated ,C .[[PendingAsyncDependencies]] 递减为 1。更新模块的字段如 表 49 所示。
表 49:模块 E 完成执行后的模块字段
字段
模块
C
E
[[DFSIndex]]
3
4
[[DFSAncestorIndex]]
0
4
[[Status]]
evaluating-async
evaluated
[[AsyncEvaluationOrder]]
3
2
[[AsyncParentModules]]
« A »
« C »
[[PendingAsyncDependencies]]
1(D )
0
D 接下来完成(因为它是唯一仍在执行的模块)。当发生这种情况时,再次调用 AsyncModuleExecutionFulfilled ,
D .[[Status]] 设置为
evaluated 。其可用于执行的祖先是 B
(其 [[AsyncEvaluationOrder]] 是 1)和 C
(其 [[AsyncEvaluationOrder]] 是 3),因此 B 将首先处理:
B .[[PendingAsyncDependencies]]
递减为 0,对 B 调用 ExecuteAsyncModule ,
它开始执行。C .[[PendingAsyncDependencies]] 也递减为
0,C 开始执行(如果 B 包含 await,可能与 B 并行)。更新模块的字段如
表 50 所示。
表 50:模块 D 完成执行后的模块字段
字段
模块
B
C
D
[[DFSIndex]]
1
3
2
[[DFSAncestorIndex]]
0
0
0
[[Status]]
evaluating-async
evaluating-async
evaluated
[[AsyncEvaluationOrder]]
1
3
0
[[AsyncParentModules]]
« A »
« A »
« B , C »
[[PendingAsyncDependencies]]
0
0
0
让我们假设 C 接下来完成执行。当发生这种情况时,再次调用 AsyncModuleExecutionFulfilled ,
C .[[Status]] 设置为
evaluated ,A .[[PendingAsyncDependencies]] 递减为 1。更新模块的字段如 表 51 所示。
表 51:模块 C 完成执行后的模块字段
字段
模块
A
C
[[DFSIndex]]
0
3
[[DFSAncestorIndex]]
0
0
[[Status]]
evaluating-async
evaluated
[[AsyncEvaluationOrder]]
4
3
[[AsyncParentModules]]
« »
« A »
[[PendingAsyncDependencies]]
1(B )
0
然后,B 完成执行。当发生这种情况时,再次调用 AsyncModuleExecutionFulfilled ,
B .[[Status]] 设置为 evaluated 。
A .[[PendingAsyncDependencies]] 递减为 0,因此调用 ExecuteAsyncModule ,
它开始执行。更新模块的字段如 表 52
所示。
表 52:模块 B 完成执行后的模块字段
字段
模块
A
B
[[DFSIndex]]
0
1
[[DFSAncestorIndex]]
0
0
[[Status]]
evaluating-async
evaluated
[[AsyncEvaluationOrder]]
4
1
[[AsyncParentModules]]
« »
« A »
[[PendingAsyncDependencies]]
0
0
最后,A 完成执行。当发生这种情况时,再次调用 AsyncModuleExecutionFulfilled ,
A .[[Status]] 设置为
evaluated 。此时,A .[[TopLevelCapability]] 中的 Promise(从
A .Evaluate() 返回)被解析,这结束了对此模块图的处理。更新模块的字段如 表 53 所示。
表 53:模块 A 完成执行后的模块字段
字段
模块
A
[[DFSIndex]]
0
[[DFSAncestorIndex]]
0
[[Status]]
evaluated
[[AsyncEvaluationOrder]]
4
[[AsyncParentModules]]
« »
[[PendingAsyncDependencies]]
0
或者,考虑失败情况,其中 C 在 B 完成执行之前执行失败并返回错误。当发生这种情况时,调用 AsyncModuleExecutionRejected ,
它设置 C .[[Status]] 为
evaluated ,C .[[EvaluationError]] 为错误。然后通过对每个 AsyncParentModules 执行 AsyncModuleExecutionRejected
将此错误传播到所有 AsyncParentModules。更新模块的字段如 表 54 所示。
表 54:模块 C 出错完成后的模块字段
字段
模块
A
C
[[DFSIndex]]
0
3
[[DFSAncestorIndex]]
0
0
[[Status]]
evaluated
evaluated
[[AsyncEvaluationOrder]]
4
3
[[AsyncParentModules]]
« »
« A »
[[PendingAsyncDependencies]]
1(B )
0
[[EvaluationError]]
empty
C 的求值错误
A 将被拒绝,错误与 C 相同,因为 C 将用 C 的错误对 A
调用 AsyncModuleExecutionRejected 。
A .[[Status]] 设置为 evaluated 。此时
A .[[TopLevelCapability]] 中的 Promise(从
A .Evaluate() 返回)被拒绝。更新模块的字段如 表
55 所示。
表 55:模块 A 被拒绝后的模块字段
字段
模块
A
[[DFSIndex]]
0
[[DFSAncestorIndex]]
0
[[Status]]
evaluated
[[AsyncEvaluationOrder]]
4
[[AsyncParentModules]]
« »
[[PendingAsyncDependencies]]
0
[[EvaluationError]]
C 的 求值 错误
然后,B 完成执行且没有错误。当发生这种情况时,再次调用 AsyncModuleExecutionFulfilled ,
B .[[Status]] 设置为 evaluated 。对
B 调用 GatherAvailableAncestors 。
然而,A .[[CycleRoot]]
是 A ,它有求值错误,因此它不会被添加到返回的 sortedExecList 中,AsyncModuleExecutionFulfilled
将返回而不进行进一步处理。B 的任何未来导入者将从 C 设置在循环根 A 上的求值错误中解析
B .[[CycleRoot]] .[[EvaluationError]] 的拒绝。更新模块的字段如 表 56 所示。
表 56:模块 B 在错误图中完成执行后的模块字段
字段
模块
A
B
[[DFSIndex]]
0
1
[[DFSAncestorIndex]]
0
0
[[Status]]
evaluated
evaluated
[[AsyncEvaluationOrder]]
4
1
[[AsyncParentModules]]
« »
« A »
[[PendingAsyncDependencies]]
0
0
[[EvaluationError]]
C 的 求值 错误
empty
16.2.1.7 源文本模块记录
源文本模块记录 用于表示从使用 目标符号 Module 解析的 ECMAScript
源文本 (11 )定义的模块信息。其字段包含关于模块导入和导出名称的摘要信息,其具体方法使用这些摘要来链接和求值模块。
源文本模块记录 可以与抽象 Module Record
类型的其他子类存在于模块图中,并且可以与 Cyclic Module Record 类型的其他子类参与循环。
除了在 表 45 中定义的字段外,源文本模块记录 还有在 表 57
中列出的其他字段。每个字段最初在 ParseModule 中设置。
表 57:源文本模块记录 的附加字段
字段名称
值类型
含义
[[ECMAScriptCode]]
一个 解析节点
使用 Module 作为
目标符号
解析此模块源文本的结果。
[[Context]]
一个 ECMAScript
代码执行上下文 或 empty
与此模块关联的 执行上下文 。在模块环境初始化之前为
empty 。
[[ImportMeta]]
一个对象或 empty
通过 import.meta 元属性暴露的对象。在被 ECMAScript 代码访问之前为
empty 。
[[ImportEntries]]
一个 列表 ,包含
ImportEntry 记录
从此模块代码派生的 ImportEntry 记录的 列表 。
[[LocalExportEntries]]
一个 列表 ,包含
ExportEntry 记录
从此模块代码派生的 ExportEntry 记录的 列表 ,对应于模块内发生的声明。
[[IndirectExportEntries]]
一个 列表 ,包含
ExportEntry 记录
从此模块代码派生的 ExportEntry 记录的 列表 ,对应于模块内发生的重新导出导入或来自
export * as namespace 声明的导出。
[[StarExportEntries]]
一个 列表 ,包含
ExportEntry 记录
从此模块代码派生的 ExportEntry 记录的 列表 ,对应于模块内发生的
export * 声明,不包括 export * as namespace 声明。
ImportEntry
记录 是一个 记录 ,摘要了关于单个声明性导入的信息。每个
ImportEntry 记录 都有在 表 58 中定义的字段:
表 58:ImportEntry 记录 字段
注 1
表
59 给出了用于表示语法导入形式的 ImportEntry 记录字段的示例:
表 59(信息性):导入形式到 ImportEntry
记录 的映射
导入语句形式
[[ModuleRequest]]
[[ImportName]]
[[LocalName]]
import v from "mod";
"mod"
"default"
"v"
import * as ns from "mod";
"mod"
namespace-object
"ns"
import {x} from "mod";
"mod"
"x"
"x"
import {x as v} from "mod";
"mod"
"x"
"v"
import "mod";
不创建 ImportEntry
记录 。
ExportEntry
记录 是一个 记录 ,摘要了关于单个声明性导出的信息。每个
ExportEntry 记录 都有在 表
60 中定义的字段:
表 60:ExportEntry 记录 字段
注 2
表
61 给出了用于表示语法导出形式的 ExportEntry 记录字段的示例:
表 61(信息性):导出形式到 ExportEntry
记录 的映射
导出语句形式
[[ExportName]]
[[ModuleRequest]]
[[ImportName]]
[[LocalName]]
export var v;
"v"
null
null
"v"
export default function f() {}
"default"
null
null
"f"
export default function () {}
"default"
null
null
"*default*"
export default 42;
"default"
null
null
"*default*"
export {x};
"x"
null
null
"x"
export {v as x};
"x"
null
null
"v"
export {x} from "mod";
"x"
"mod"
"x"
null
export {v as x} from "mod";
"x"
"mod"
"v"
null
export * from "mod";
null
"mod"
all-but-default
null
export * as ns from "mod";
"ns"
"mod"
all
null
以下定义指定了 源文本模块记录 所需的具体方法和其他 抽象操作
16.2.1.7.1 ParseModule ( sourceText ,
realm , hostDefined )
抽象操作 ParseModule 接受参数 sourceText (ECMAScript
源文本 )、realm (一个 Realm Record )和
hostDefined (任意值),返回一个 源文本模块记录 或一个非空的
列表 ,包含
SyntaxError 对象。它基于将 sourceText 作为 Module 解析的结果创建一个 源文本模块记录 。调用时执行以下步骤:
设 body 为 ParseText (sourceText ,
Module )。
如果 body 是一个错误的 列表 ,返回
body 。
设 requestedModules 为 body 的 ModuleRequests 。
设 importEntries 为 body 的 ImportEntries 。
设 importedBoundNames 为 ImportedLocalNames (importEntries )。
设 indirectExportEntries 为一个新的空 列表 。
设 localExportEntries 为一个新的空 列表 。
设 starExportEntries 为一个新的空 列表 。
设 exportEntries 为 body 的 ExportEntries 。
对于 exportEntries 中的每个 ExportEntry
Record
ee ,执行
如果 ee .[[ModuleRequest]] 是
null ,那么
如果 importedBoundNames 不包含
ee .[[LocalName]] ,那么
将 ee 附加到 localExportEntries 。
否则,
设 ie 为 importEntries 中 [[LocalName]] 是
ee .[[LocalName]]
的元素。
如果 ie .[[ImportName]]
是 namespace-object ,那么
注:这是对导入模块命名空间对象的重新导出。
将 ee 附加到
localExportEntries 。
否则,
注:这是对单个名称的重新导出。
将 ExportEntry
Record { [[ModuleRequest]] :
ie .[[ModuleRequest]] , [[ImportName]] :
ie .[[ImportName]] , [[LocalName]] :
null , [[ExportName]] :
ee .[[ExportName]] }
附加到
indirectExportEntries 。
否则如果 ee .[[ImportName]] 是
all-but-default ,那么
断言 :ee .[[ExportName]] 是
null 。
将 ee 附加到 starExportEntries 。
否则,
将 ee 附加到 indirectExportEntries 。
设 async 为 body Contains
await。
返回 源文本模块记录
{ [[Realm]] : realm , [[Environment]] : empty , [[Namespace]] : empty , [[CycleRoot]] : empty , [[HasTLA]] : async , [[AsyncEvaluationOrder]] : unset ,
[[TopLevelCapability]] : empty ,
[[AsyncParentModules]] : « », [[PendingAsyncDependencies]] :
empty , [[Status]] :
new , [[EvaluationError]] :
empty , [[HostDefined]] :
hostDefined , [[ECMAScriptCode]] :
body , [[Context]] :
empty , [[ImportMeta]] :
empty , [[RequestedModules]] :
requestedModules , [[LoadedModules]] :
« », [[ImportEntries]] : importEntries ,
[[LocalExportEntries]] : localExportEntries ,
[[IndirectExportEntries]] :
indirectExportEntries , [[StarExportEntries]] : starExportEntries ,
[[DFSIndex]] : empty , [[DFSAncestorIndex]] :
empty }。
注
实现可能在对该模块源文本求值 ParseModule 之前解析模块源文本并分析其早期错误条件。然而,任何错误的报告都必须推迟到本规范实际对该源文本执行
ParseModule 的时刻。
16.2.1.7.2 模块记录抽象方法的实现
以下是 源文本模块记录 的具体方法,实现了 表 44 中定义的相应
模块记录 抽象方法。
16.2.1.7.2.1 GetExportedNames ( [
exportStarSet ] )
源文本模块记录 module 的
GetExportedNames 具体方法接受可选参数
exportStarSet (一个包含 源文本模块记录 的
列表 ),返回一个包含字符串的
列表 。调用时执行以下步骤:
断言 :module .[[Status]] 不是 new 。
如果 exportStarSet 不存在,设 exportStarSet 为一个新的空 列表 。
如果 exportStarSet 包含 module ,那么
断言 :我们已达到 export *
循环的起点。
返回一个新的空 列表 。
将 module 附加到 exportStarSet 。
设 exportedNames 为一个新的空 列表 。
对于 module .[[LocalExportEntries]] 中的每个
ExportEntry Record
e ,执行
断言 :module
为此导出提供直接绑定。
断言 :e .[[ExportName]] 不是
null 。
将 e .[[ExportName]] 附加到
exportedNames 。
对于 module .[[IndirectExportEntries]] 中的每个
ExportEntry Record
e ,执行
断言 :module
为此导出导入特定绑定。
断言 :e .[[ExportName]] 不是
null 。
将 e .[[ExportName]] 附加到
exportedNames 。
对于 module .[[StarExportEntries]] 中的每个
ExportEntry Record
e ,执行
断言 :e .[[ModuleRequest]] 不是
null 。
设 requestedModule 为 GetImportedModule (module ,
e .[[ModuleRequest]] )。
设 starNames 为
requestedModule .GetExportedNames(exportStarSet )。
对于 starNames 的每个元素 n ,执行
如果 n 不是 "default" ,那么
如果 exportedNames 不包含
n ,那么
将 n 附加到
exportedNames 。
返回 exportedNames 。
注
GetExportedNames 不会过滤掉或为具有歧义星号导出绑定的名称抛出异常。
16.2.1.7.2.2 ResolveExport ( exportName [ ,
resolveSet ] )
源文本模块记录 module 的
ResolveExport 具体方法接受参数 exportName (一个字符串)和可选参数
resolveSet (一个包含字段 [[Module]] (一个 模块记录 )和 [[ExportName]] (一个字符串)的 记录 的 列表 ),返回一个
ResolvedBinding
Record 、null 或
ambiguous 。
ResolveExport 尝试将导入绑定解析为实际的定义模块和本地绑定名称。定义模块可能是调用此方法的 模块记录 所表示的模块,或该模块导入的其他模块。参数
resolveSet 用于检测未解析的循环导入/导出路径。如果到达的特定 模块记录 和
exportName 的配对已在 resolveSet 中,则遇到了导入循环。在递归调用 ResolveExport
之前,由 module 和
exportName 组成的配对会添加到 resolveSet 。
如果找到定义模块,返回一个 ResolvedBinding
Record { [[Module]] , [[BindingName]]
}。此记录标识最初请求导出的已解析绑定,除非这是没有本地绑定的命名空间导出。在这种情况下,[[BindingName]] 将设置为
namespace 。如果没有找到定义或请求被发现是循环的,返回
null 。如果请求被发现是歧义的,返回 ambiguous 。
调用时执行以下步骤:
断言 :module .[[Status]] 不是 new 。
如果 resolveSet 不存在,设 resolveSet 为一个新的空 列表 。
对于 resolveSet 中的每个 记录
{ [[Module]] , [[ExportName]] } r ,执行
如果 module 和 r .[[Module]] 是同一个 模块记录 且
exportName 是
r .[[ExportName]] ,那么
断言 :这是一个循环导入请求。
返回 null 。
将 记录
{ [[Module]] : module , [[ExportName]] : exportName } 附加到
resolveSet 。
对于 module .[[LocalExportEntries]] 中的每个
ExportEntry Record
e ,执行
如果 e .[[ExportName]] 是
exportName ,那么
断言 :
module 为此导出提供直接绑定。
返回 ResolvedBinding
Record { [[Module]] : module , [[BindingName]] : e .[[LocalName]] }。
对于 module .[[IndirectExportEntries]] 中的每个
ExportEntry Record
e ,执行
如果 e .[[ExportName]] 是
exportName ,那么
断言 :
e .[[ModuleRequest]] 不是
null 。
设 importedModule 为 GetImportedModule (module ,
e .[[ModuleRequest]] )。
如果 e .[[ImportName]] 是
all ,那么
断言 :
module 不为此导出提供直接绑定。
返回 ResolvedBinding
Record { [[Module]] :
importedModule , [[BindingName]] :
namespace }。
否则,
断言 :
module 为此导出导入特定绑定。
断言 :
e .[[ImportName]]
是一个字符串 。
返回
importedModule .ResolveExport(e .[[ImportName]] ,
resolveSet )。
如果 exportName 是 "default" ,那么
断言 :此模块没有显式定义
default 导出。
返回 null 。
注:default 导出不能由 export * from "mod" 声明提供。
设 starResolution 为 null 。
对于 module .[[StarExportEntries]] 中的每个
ExportEntry Record
e ,执行
断言 :e .[[ModuleRequest]] 不是
null 。
设 importedModule 为 GetImportedModule (module ,
e .[[ModuleRequest]] )。
设 resolution 为
importedModule .ResolveExport(exportName ,
resolveSet )。
如果 resolution 是 ambiguous ,返回
ambiguous 。
如果 resolution 不是 null ,那么
断言 :
resolution 是一个 ResolvedBinding
Record 。
如果 starResolution 是 null ,那么
设 starResolution 为
resolution 。
否则,
断言 :有多个包含请求名称的
* 导入。
如果 resolution .[[Module]] 和
starResolution .[[Module]] 不是同一个 模块记录 ,返回
ambiguous 。
如果 resolution .[[BindingName]] 不是
starResolution .[[BindingName]] 且
resolution .[[BindingName]] 或
starResolution .[[BindingName]] 中的任一个是
namespace ,返回
ambiguous 。
如果 resolution .[[BindingName]] 是一个字符串 ,
starResolution .[[BindingName]] 是一个字符串 ,且
resolution .[[BindingName]] 不是
starResolution .[[BindingName]] ,返回
ambiguous 。
返回 starResolution 。
16.2.1.7.3 循环模块记录抽象方法的实现
以下是 源文本模块记录 的具体方法,实现了 表 46 中定义的相应 循环模块记录 抽象方法。
16.2.1.7.3.1 InitializeEnvironment ( )
源文本模块记录
module 的 InitializeEnvironment 具体方法不接受参数,返回 包含
unused 的正常完成,或 抛出完成 。调用时执行以下步骤:
对于 module .[[IndirectExportEntries]] 中的每个
ExportEntry Record
e ,执行
断言 :e .[[ExportName]] 不是
null 。
设 resolution 为
module .ResolveExport(e .[[ExportName]] )。
如果 resolution 是 null 或
ambiguous ,抛出 SyntaxError
异常。
断言 :resolution
是一个 ResolvedBinding
Record 。
断言 :module 的所有命名导出都是可解析的。
设 realm 为 module .[[Realm]] 。
断言 :realm 不是
undefined 。
设 env 为 NewModuleEnvironment (realm .[[GlobalEnv]] )。
设 module .[[Environment]] 为
env 。
对于 module .[[ImportEntries]] 中的每个
ImportEntry Record
in ,执行
设 importedModule 为 GetImportedModule (module ,
in .[[ModuleRequest]] )。
如果 in .[[ImportName]] 是
namespace-object ,那么
设 namespace 为 GetModuleNamespace (importedModule )。
执行
! env .CreateImmutableBinding(in .[[LocalName]] ,
true )。
执行
! env .InitializeBinding(in .[[LocalName]] ,
namespace )。
否则,
设 resolution 为
importedModule .ResolveExport(in .[[ImportName]] )。
如果 resolution 是 null
或 ambiguous ,抛出
SyntaxError 异常。
如果 resolution .[[BindingName]] 是
namespace ,那么
设 namespace 为 GetModuleNamespace (resolution .[[Module]] )。
执行
! env .CreateImmutableBinding(in .[[LocalName]] ,
true )。
执行
! env .InitializeBinding(in .[[LocalName]] ,
namespace )。
否则,
执行 CreateImportBinding (env ,
in .[[LocalName]] ,
resolution .[[Module]] ,
resolution .[[BindingName]] )。
设 moduleContext 为一个新的 ECMAScript
代码执行上下文 。
设 moduleContext 的 Function 为 null 。
断言 :module .[[Realm]] 不是 undefined 。
设 moduleContext 的 Realm 为
module .[[Realm]] 。
设 moduleContext 的 ScriptOrModule 为 module 。
设 moduleContext 的 VariableEnvironment 为
module .[[Environment]] 。
设 moduleContext 的 LexicalEnvironment 为
module .[[Environment]] 。
设 moduleContext 的 PrivateEnvironment 为
null 。
设 module .[[Context]] 为
moduleContext 。
将 moduleContext 压入 执行上下文栈 ;moduleContext
现在是 运行的执行上下文 。
设 code 为 module .[[ECMAScriptCode]] 。
设 varDeclarations 为 code 的 VarScopedDeclarations 。
设 declaredVarNames 为一个新的空 列表 。
对于 varDeclarations 的每个元素 d ,执行
对于 d 的 BoundNames
的每个元素 dn ,执行
如果 declaredVarNames 不包含
dn ,那么
执行
! env .CreateMutableBinding(dn ,
false )。
执行
! env .InitializeBinding(dn ,
undefined )。
将 dn 附加到 declaredVarNames 。
设 lexDeclarations 为 code 的 LexicallyScopedDeclarations 。
设 privateEnv 为 null 。
对于 lexDeclarations 的每个元素 d ,执行
对于 d 的 BoundNames
的每个元素 dn ,执行
如果 d 的 IsConstantDeclaration
是 true ,那么
执行
! env .CreateImmutableBinding(dn ,
true )。
否则,
执行
! env .CreateMutableBinding(dn ,
false )。
如果 d 是 FunctionDeclaration 、GeneratorDeclaration 、AsyncFunctionDeclaration
或 AsyncGeneratorDeclaration ,那么
设 fo 为 d 的 InstantiateFunctionObject ,参数为
env 和
privateEnv 。
执行
! env .InitializeBinding(dn ,
fo )。
从 执行上下文栈 中移除
moduleContext 。
返回 unused 。
16.2.1.7.3.2 ExecuteModule ( [ capability ] )
源文本模块记录 module 的
ExecuteModule 具体方法接受可选参数
capability (一个 PromiseCapability
Record ),返回 包含
unused 的正常完成,或 抛出完成 。调用时执行以下步骤:
设 moduleContext 为一个新的 ECMAScript
代码执行上下文 。
设 moduleContext 的 Function 为 null 。
设 moduleContext 的 Realm 为
module .[[Realm]] 。
设 moduleContext 的 ScriptOrModule 为 module 。
断言 :module
已被链接,其模块环境中的声明已被实例化。
设 moduleContext 的 VariableEnvironment 为
module .[[Environment]] 。
设 moduleContext 的 LexicalEnvironment 为
module .[[Environment]] 。
暂停 运行的执行上下文 。
如果 module .[[HasTLA]] 是
false ,那么
断言 :capability
不存在。
将 moduleContext 压入 执行上下文栈 ;moduleContext
现在是
运行的执行上下文 。
设 result 为 Completion (module .[[ECMAScriptCode]] 的 Evaluation )。
暂停 moduleContext 并从 执行上下文栈 中移除它。
恢复现在位于 执行上下文栈
顶部的上下文作为 运行的执行上下文 。
如果 result 是一个 异常完成 ,那么
返回 ? result 。
否则,
断言 :capability
是一个 PromiseCapability
Record 。
执行 AsyncBlockStart (capability ,
module .[[ECMAScriptCode]] ,
moduleContext )。
返回 unused 。
16.2.1.8 合成模块记录
合成模块记录 用于表示由规范定义的模块的信息。其导出名称在创建时静态定义,而其对应的值可以通过 SetSyntheticModuleExport
随时间变化。它没有导入或依赖项。
注
合成模块记录可用于定义各种模块类型:例如,JSON 模块或 CSS 模块。
除了 表 43 中定义的字段外,合成模块记录还具有 表 62 中列出的附加字段。
表 62:合成模块记录 的附加字段
字段名称
值类型
含义
[[ExportNames]]
字符串的 列表
模块的导出名称。此列表不包含重复项。
[[EvaluationSteps]]
一个 抽象闭包
在模块求值时执行的初始化逻辑,以 合成模块记录 作为其唯一参数。它不得修改
[[ExportNames]] 。它可能返回一个 异常完成 。
16.2.1.8.1 CreateDefaultExportSyntheticModule (
defaultExport )
抽象操作 CreateDefaultExportSyntheticModule 接受参数
defaultExport (一个 ECMAScript
语言值 ),返回一个 合成模块记录 。它创建一个默认导出为
defaultExport 的 合成模块记录 。调用时执行以下步骤:
设 realm 为 当前 Realm Record 。
设 setDefaultExport 为一个新的 抽象闭包 ,参数为
(module ),捕获
defaultExport 并在调用时执行以下步骤:
执行 SetSyntheticModuleExport (module ,
"default" , defaultExport )。
返回 NormalCompletion (unused )。
返回 合成模块记录 { [[Realm]] :
realm , [[Environment]] :
empty , [[Namespace]] :
empty , [[HostDefined]] :
undefined , [[ExportNames]] : «
"default" », [[EvaluationSteps]] : setDefaultExport }。
16.2.1.8.2 ParseJSONModule ( source )
抽象操作 ParseJSONModule 接受参数 source (一个字符串),返回 包含 一个 合成模块记录 的正常完成,或 抛出完成 。调用时执行以下步骤:
设 json 为 ? ParseJSON (source )。
返回 CreateDefaultExportSyntheticModule (json )。
16.2.1.8.3 SetSyntheticModuleExport ( module ,
exportName , exportValue )
抽象操作 SetSyntheticModuleExport 接受参数 module (一个 合成模块记录 )、exportName (一个字符串)和
exportValue (一个 ECMAScript
语言值 ),返回 unused 。它可用于设置或更改 合成模块记录 现有导出的导出值。调用时执行以下步骤:
断言 :
module .[[ExportNames]] 包含
exportName 。
设 envRec 为 module .[[Environment]] 。
断言 :
envRec 不是 empty 。
执行 envRec .SetMutableBinding(exportName ,
exportValue , true )。
返回 unused 。
16.2.1.8.4 模块记录抽象方法的实现
以下是 合成模块记录 的具体方法,实现了 表 44 中定义的相应
模块记录 抽象方法。
16.2.1.8.4.1 LoadRequestedModules ( )
合成模块记录
module 的 LoadRequestedModules 具体方法不接受参数,返回一个 Promise。调用时执行以下步骤:
返回 ! PromiseResolve (%Promise% ,
undefined )。
注
16.2.1.8.4.2 GetExportedNames ( )
合成模块记录
module 的 GetExportedNames 具体方法不接受参数,返回一个包含字符串的 列表 。调用时执行以下步骤:
返回 module .[[ExportNames]] 。
16.2.1.8.4.3 ResolveExport ( exportName )
合成模块记录 module
的 ResolveExport 具体方法接受参数 exportName (一个字符串),返回一个 ResolvedBinding Record 或
null 。调用时执行以下步骤:
如果 module .[[ExportNames]] 不包含
exportName ,返回 null 。
返回 ResolvedBinding Record
{ [[Module]] : module , [[BindingName]] : exportName }。
16.2.1.8.4.4 Link ( )
合成模块记录 module
的 Link 具体方法不接受参数,返回 包含
unused 的正常完成。调用时执行以下步骤:
设 realm 为 module .[[Realm]] 。
设 env 为 NewModuleEnvironment (realm .[[GlobalEnv]] )。
设 module .[[Environment]] 为
env 。
对于 module .[[ExportNames]] 的每个字符串
exportName ,执行
执行
! env .CreateMutableBinding(exportName ,
false )。
执行
! env .InitializeBinding(exportName ,
undefined )。
返回 NormalCompletion (unused )。
16.2.1.8.4.5 Evaluate ( )
合成模块记录 module
的 Evaluate 具体方法不接受参数,返回一个 Promise。调用时执行以下步骤:
设 moduleContext 为一个新的 ECMAScript
代码执行上下文 。
设 moduleContext 的 Function 为 null 。
设 moduleContext 的 Realm 为
module .[[Realm]] 。
设 moduleContext 的 ScriptOrModule 为 module 。
设 moduleContext 的 VariableEnvironment 为
module .[[Environment]] 。
设 moduleContext 的 LexicalEnvironment 为
module .[[Environment]] 。
暂停 运行的执行上下文 。
将 moduleContext 压入 执行上下文栈 ;moduleContext
现在是 运行的执行上下文 。
设 steps 为 module .[[EvaluationSteps]] 。
设 result 为 Completion (steps (module ))。
暂停 moduleContext 并从 执行上下文栈
中移除它。
恢复现在位于 执行上下文栈 顶部的上下文作为
运行的执行上下文 。
设 pc 为 ! NewPromiseCapability (%Promise% )。
IfAbruptRejectPromise (result ,
pc )。
执行 ! Call (pc .[[Resolve]] , undefined , «
undefined »)。
返回 pc .[[Promise]] 。
16.2.1.9 GetImportedModule ( referrer ,
request )
抽象操作 GetImportedModule 接受参数 referrer (一个 循环模块记录 )和
request (一个 ModuleRequest Record ),返回一个 模块记录 。调用时执行以下步骤:
设 records 为一个 列表 ,由
referrer .[[LoadedModules]] 中满足 ModuleRequestsEqual (r ,
request ) 为 true 的每个 LoadedModuleRequest Record
r 组成。
断言 :
records 恰好有一个元素,因为在调用此抽象操作之前,LoadRequestedModules 已在 referrer
上成功完成。
设 record 为 records 的唯一元素。
返回 record .[[Module]] 。
16.2.1.10 HostLoadImportedModule ( referrer ,
moduleRequest , hostDefined , payload )
宿主定义 的抽象操作
HostLoadImportedModule 接受参数 referrer (一个 脚本记录 、一个 循环模块记录 或一个 Realm
Record )、moduleRequest (一个 ModuleRequest
Record )、hostDefined (任何值)和 payload (一个 GraphLoadingState Record 或一个
PromiseCapability Record ),返回
unused 。
注 1
referrer 可以是 Realm Record 的一个例子是在 Web 浏览器 宿主 中。在那里,如果用户点击由以下代码给出的控件
<button type ="button" onclick ="import('./foo.mjs')" > Click me</button >
当 import() 表达式运行时,将没有
活动脚本或模块 。更一般地,这可能发生在
宿主 将具有
null ScriptOrModule 组件的 执行上下文 推入
执行上下文栈 的任何情况下。
HostLoadImportedModule 的实现必须符合以下要求:
宿主环境 必须执行 FinishLoadingImportedModule (referrer ,
moduleRequest , payload , result ),其中
result 是 包含 已加载的 模块记录 的正常完成或 抛出完成 ,可以是同步或异步的。
如果此操作被多次调用,使用两个 (referrer ,
moduleRequest ) 对,满足:
第一个 referrer 与第二个 referrer 相同;
ModuleRequestsEqual (第一个
moduleRequest , 第二个 moduleRequest ) 为
true ;
并且它执行 FinishLoadingImportedModule (referrer ,
moduleRequest , payload , result ),其中
result 是 正常完成 ,那么它必须每次都用相同的
result 执行 FinishLoadingImportedModule (referrer ,
moduleRequest , payload , result )。
如果 moduleRequest .[[Attributes]] 有一个条目
entry ,使得 entry .[[Key]] 是
"type" 且 entry .[[Value]] 是
"json" ,当 宿主环境
执行 FinishLoadingImportedModule (referrer ,
moduleRequest , payload , result ) 时,result
必须是调用 ParseJSONModule 返回的 完成记录 或
抛出完成 。
操作必须将 payload 视为要传递给
FinishLoadingImportedModule
的不透明值。
执行的实际过程是 宿主定义 的,但通常包括执行加载适当的 模块记录 所需的任何 I/O 操作。多个不同的
(referrer , moduleRequest .[[Specifier]] ,
moduleRequest .[[Attributes]] ) 三元组可能映射到同一个 模块记录 实例。实际的映射语义是 宿主定义 的,但通常作为映射过程的一部分,会对 specifier
应用规范化过程。典型的规范化过程包括扩展相对和缩写路径说明符等操作。
注 2
上述文本要求 宿主 在使用
type: "json" 导入时支持 JSON 模块(并且 HostLoadImportedModule 正常完成),但它不禁止
宿主 在不使用
type: "json" 导入时支持 JSON 模块。
16.2.1.11 FinishLoadingImportedModule ( referrer ,
moduleRequest , payload , result )
抽象操作 FinishLoadingImportedModule 接受参数 referrer (一个 脚本记录 、一个 循环模块记录 或一个 Realm
Record )、moduleRequest (一个 ModuleRequest
Record )、payload (一个 GraphLoadingState Record 或一个
PromiseCapability Record )和
result (包含 一个
模块记录 的正常完成或 抛出完成 ),返回
unused 。调用时执行以下步骤:
如果 result 是 正常完成 ,那么
如果 referrer .[[LoadedModules]] 包含一个
LoadedModuleRequest
Record record ,使得 ModuleRequestsEqual (record ,
moduleRequest ) 为 true ,那么
断言 :record .[[Module]] 和 result .[[Value]] 是同一个 模块记录 。
否则,
将 LoadedModuleRequest
Record { [[Specifier]] : moduleRequest .[[Specifier]] , [[Attributes]] :
moduleRequest .[[Attributes]] ,
[[Module]] : result .[[Value]] } 附加到
referrer .[[LoadedModules]] 。
如果 payload 是 GraphLoadingState
Record ,那么
执行 ContinueModuleLoading (payload ,
result )。
否则,
执行 ContinueDynamicImport (payload ,
result )。
返回 unused 。
16.2.1.12 AllImportAttributesSupported ( attributes )
抽象操作 AllImportAttributesSupported 接受参数 attributes (一个包含 ImportAttribute Records 的 列表 ),返回一个布尔值。调用时执行以下步骤:
设 supported 为 HostGetSupportedImportAttributes ()。
对于 attributes 的每个 ImportAttribute
Record
attribute ,执行
如果 supported 不包含 attribute .[[Key]] ,返回 false 。
返回 true 。
16.2.1.12.1 HostGetSupportedImportAttributes ( )
宿主定义 的抽象操作
HostGetSupportedImportAttributes 不接受参数,返回一个包含字符串的 列表 。它允许 宿主环境 指定它们支持的导入属性。只有具有受支持键的属性才会提供给
宿主 。
HostGetSupportedImportAttributes 的实现必须符合以下要求:
它必须返回一个包含字符串的 列表 ,每个字符串表示一个受支持的属性。
每次调用此操作时,它必须返回相同的 列表 ,包含相同顺序的相同内容。
HostGetSupportedImportAttributes 的默认实现是返回一个新的空 列表 。
注
要求
宿主 指定其受支持的导入属性,而不是将所有属性传递给
宿主 并让其选择要处理哪些属性的目的,是确保不受支持的属性在不同
宿主 之间以一致的方式处理。
16.2.1.13 GetModuleNamespace ( module )
抽象操作 GetModuleNamespace 接受参数 module (模块记录 具体子类的实例),返回一个模块命名空间对象。它检索表示
module 导出的模块命名空间对象,在第一次请求时惰性创建它,并将其存储在 module .[[Namespace]] 中以供将来检索。调用时执行以下步骤:
断言 :如果
module 是 循环模块记录 ,那么
module .[[Status]] 不是
new 或 unlinked 。
设 namespace 为 module .[[Namespace]] 。
如果 namespace 是 empty ,那么
设 exportedNames 为 module .GetExportedNames()。
设 unambiguousNames 为一个新的空 列表 。
对于 exportedNames 的每个元素 name ,执行
设 resolution 为
module .ResolveExport(name )。
如果 resolution 是 ResolvedBinding
Record ,将 name 附加到
unambiguousNames 。
设 namespace 为 ModuleNamespaceCreate (module ,
unambiguousNames )。
返回 namespace 。
注
GetModuleNamespace
永远不会抛出异常。相反,无法解析的名称在此时简单地从命名空间中排除。除非它们都是未在任何地方明确请求的歧义星号导出,否则稍后会导致真正的链接错误。
16.2.1.14 运行时语义:求值
Module : [empty]
返回 undefined 。
ModuleBody : ModuleItemList
设 result 为 Completion (ModuleItemList 的
求值 )。
如果 result 是 正常完成 且
result .[[Value]] 是
empty ,那么
返回 undefined 。
返回 ? result 。
ModuleItemList :
ModuleItemList
ModuleItem
设 sl 为 ? ModuleItemList 的 求值 。
设 s 为 Completion (ModuleItem 的 求值 )。
返回 ? UpdateEmpty (s ,
sl )。
注
ModuleItem : ImportDeclaration
返回 empty 。
16.2.2 导入
语法
ImportDeclaration
:
import
ImportClause
FromClause
WithClause opt
;
import
ModuleSpecifier
WithClause opt
;
ImportClause :
ImportedDefaultBinding
NameSpaceImport
NamedImports
ImportedDefaultBinding
,
NameSpaceImport
ImportedDefaultBinding
,
NamedImports
ImportedDefaultBinding
:
ImportedBinding
NameSpaceImport :
*
as
ImportedBinding
NamedImports :
{
}
{
ImportsList
}
{
ImportsList
,
}
FromClause :
from
ModuleSpecifier
ImportsList :
ImportSpecifier
ImportsList
,
ImportSpecifier
ImportSpecifier :
ImportedBinding
ModuleExportName
as
ImportedBinding
ModuleSpecifier :
StringLiteral
ImportedBinding :
BindingIdentifier [~Yield,
+Await]
WithClause :
with
{
}
with
{
WithEntries
,opt
}
WithEntries :
AttributeKey
:
StringLiteral
AttributeKey
:
StringLiteral
,
WithEntries
AttributeKey :
IdentifierName
StringLiteral
16.2.2.1 静态语义:早期错误
ModuleItem : ImportDeclaration
WithClause :
with
{
WithEntries
,opt
}
16.2.2.2 静态语义:ImportEntries
语法导向操作
ImportEntries 不接受参数,返回一个包含 ImportEntry
Records 的 列表 。它在以下产生式上分段定义:
Module : [empty]
返回一个新的空 列表 。
ModuleItemList :
ModuleItemList
ModuleItem
设 entries1 为 ModuleItemList 的 ImportEntries 。
设 entries2 为 ModuleItem 的 ImportEntries 。
返回 entries1 和 entries2 的 列表连接 。
ModuleItem :
ExportDeclaration
StatementListItem
返回一个新的空 列表 。
ImportDeclaration
:
import
ImportClause
FromClause
WithClause opt
;
设 module 为 ImportDeclaration 的 ModuleRequests
的唯一元素。
返回 ImportClause
以参数 module 的 ImportEntriesForModule 。
ImportDeclaration
:
import
ModuleSpecifier
WithClause opt
;
返回一个新的空 列表 。
16.2.2.3 静态语义:ImportEntriesForModule
语法导向操作
ImportEntriesForModule 接受参数 module (一个 ModuleRequest
Record ),返回一个包含 ImportEntry
Records 的 列表 。它在以下产生式上分段定义:
ImportClause :
ImportedDefaultBinding
,
NameSpaceImport
设 entries1 为 ImportedDefaultBinding 以参数
module 的 ImportEntriesForModule 。
设 entries2 为 NameSpaceImport 以参数
module 的 ImportEntriesForModule 。
返回 entries1 和 entries2 的 列表连接 。
ImportClause :
ImportedDefaultBinding
,
NamedImports
设 entries1 为 ImportedDefaultBinding 以参数
module 的 ImportEntriesForModule 。
设 entries2 为 NamedImports
以参数 module 的 ImportEntriesForModule 。
返回 entries1 和 entries2 的 列表连接 。
ImportedDefaultBinding
: ImportedBinding
设 localName 为 ImportedBinding 的 BoundNames 的唯一元素。
设 defaultEntry 为 ImportEntry Record {
[[ModuleRequest]] : module , [[ImportName]] : "default" , [[LocalName]] : localName }。
返回 « defaultEntry »。
NameSpaceImport
:
*
as
ImportedBinding
设 localName 为 ImportedBinding 的 StringValue 。
设 entry 为 ImportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : namespace-object ,
[[LocalName]] : localName }。
返回 « entry »。
NamedImports :
{
}
返回一个新的空 列表 。
ImportsList :
ImportsList
,
ImportSpecifier
设 specs1 为 ImportsList 以参数 module 的
ImportEntriesForModule 。
设 specs2 为 ImportSpecifier 以参数
module 的 ImportEntriesForModule 。
返回 specs1 和 specs2 的 列表连接 。
ImportSpecifier
: ImportedBinding
设 localName 为 ImportedBinding 的 BoundNames 的唯一元素。
设 entry 为 ImportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : localName , [[LocalName]] : localName }。
返回 « entry »。
ImportSpecifier
:
ModuleExportName
as
ImportedBinding
设 importName 为 ModuleExportName 的 StringValue 。
设 localName 为 ImportedBinding 的 StringValue 。
设 entry 为 ImportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : importName , [[LocalName]] : localName }。
返回 « entry »。
16.2.2.4 静态语义:WithClauseToAttributes
语法导向操作
WithClauseToAttributes 不接受参数,返回一个包含 ImportAttribute Records
的 列表 。它在以下产生式上分段定义:
WithClause :
with
{
}
返回一个新的空 列表 。
WithClause :
with
{
WithEntries
,opt
}
设 attributes 为 WithEntries 的 WithClauseToAttributes 。
根据 attributes 的 [[Key]] 字段的字典序对其进行排序,将每个这样的字段值视为
UTF-16 代码单元值的序列。注:此排序仅在禁止 宿主 根据属性枚举的顺序改变行为时可观察到。
返回 attributes 。
WithEntries :
AttributeKey
:
StringLiteral
设 key 为 AttributeKey 的 PropName 。
设 entry 为 ImportAttribute
Record { [[Key]] : key ,
[[Value]] : StringLiteral 的 SV }。
返回 « entry »。
WithEntries :
AttributeKey
:
StringLiteral
,
WithEntries
设 key 为 AttributeKey 的 PropName 。
设 entry 为 ImportAttribute
Record { [[Key]] : key ,
[[Value]] : StringLiteral 的 SV }。
设 rest 为 WithEntries 的 WithClauseToAttributes 。
返回 « entry » 和 rest 的 列表连接 。
16.2.3 导出
语法
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
export
NamedExports
;
export
VariableStatement [~Yield,
+Await]
export
Declaration [~Yield,
+Await]
export
default
HoistableDeclaration [~Yield,
+Await, +Default]
export
default
ClassDeclaration [~Yield,
+Await, +Default]
export
default
[lookahead ∉ { function , async
[no LineTerminator here]
function , class }]
AssignmentExpression [+In,
~Yield, +Await]
;
ExportFromClause :
*
*
as
ModuleExportName
NamedExports
NamedExports :
{
}
{
ExportsList
}
{
ExportsList
,
}
ExportsList :
ExportSpecifier
ExportsList
,
ExportSpecifier
ExportSpecifier :
ModuleExportName
ModuleExportName
as
ModuleExportName
16.2.3.1 静态语义:早期错误
ExportDeclaration
:
export
NamedExports
;
注
16.2.3.2 静态语义:ExportedBindings
语法导向操作
ExportedBindings 不接受参数,返回一个字符串 列表 。
注
ExportedBindings 是与 Module 的 ExportedNames
明确关联的本地绑定名称。
它在以下产生式上分段定义:
ModuleItemList :
ModuleItemList
ModuleItem
设 names1 为 ModuleItemList 的 ExportedBindings 。
设 names2 为 ModuleItem 的 ExportedBindings 。
返回 names1 和 names2 的 列表连接 。
ModuleItem :
ImportDeclaration
StatementListItem
返回一个新的空 列表 。
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
返回一个新的空 列表 。
ExportDeclaration
:
export
NamedExports
;
返回 NamedExports 的
ExportedBindings 。
ExportDeclaration
:
export
VariableStatement
返回 VariableStatement 的 BoundNames 。
ExportDeclaration
:
export
Declaration
返回 Declaration 的
BoundNames 。
ExportDeclaration
:
export
default
HoistableDeclaration
export
default
ClassDeclaration
export
default
AssignmentExpression
;
返回此 ExportDeclaration 的 BoundNames 。
NamedExports :
{
}
返回一个新的空 列表 。
ExportsList :
ExportsList
,
ExportSpecifier
设 names1 为 ExportsList 的 ExportedBindings 。
设 names2 为 ExportSpecifier 的 ExportedBindings 。
返回 names1 和 names2 的 列表连接 。
ExportSpecifier
: ModuleExportName
返回一个 列表 ,其唯一元素是
ModuleExportName 的 StringValue 。
ExportSpecifier
:
ModuleExportName
as
ModuleExportName
返回一个 列表 ,其唯一元素是第一个
ModuleExportName 的 StringValue 。
16.2.3.3 静态语义:ExportedNames
语法导向操作
ExportedNames 不接受参数,返回一个字符串 列表 。
注
ExportedNames 是 Module
明确映射到其本地名称绑定之一的外部可见名称。
它在以下产生式上分段定义:
ModuleItemList :
ModuleItemList
ModuleItem
设 names1 为 ModuleItemList 的 ExportedNames 。
设 names2 为 ModuleItem 的 ExportedNames 。
返回 names1 和 names2 的 列表连接 。
ModuleItem : ExportDeclaration
返回 ExportDeclaration 的 ExportedNames 。
ModuleItem :
ImportDeclaration
StatementListItem
返回一个新的空 列表 。
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
返回 ExportFromClause 的 ExportedNames 。
ExportFromClause
: *
返回一个新的空 列表 。
ExportFromClause
:
*
as
ModuleExportName
返回一个 列表 ,其唯一元素是
ModuleExportName 的 StringValue 。
ExportFromClause
: NamedExports
返回 NamedExports 的
ExportedNames 。
ExportDeclaration
:
export
VariableStatement
返回 VariableStatement 的 BoundNames 。
ExportDeclaration
:
export
Declaration
返回 Declaration 的
BoundNames 。
ExportDeclaration
:
export
default
HoistableDeclaration
export
default
ClassDeclaration
export
default
AssignmentExpression
;
返回 « "default" »。
NamedExports :
{
}
返回一个新的空 列表 。
ExportsList :
ExportsList
,
ExportSpecifier
设 names1 为 ExportsList 的 ExportedNames 。
设 names2 为 ExportSpecifier 的 ExportedNames 。
返回 names1 和 names2 的 列表连接 。
ExportSpecifier
: ModuleExportName
返回一个 列表 ,其唯一元素是
ModuleExportName 的 StringValue 。
ExportSpecifier
:
ModuleExportName
as
ModuleExportName
返回一个 列表 ,其唯一元素是第二个
ModuleExportName 的 StringValue 。
16.2.3.4 静态语义:ExportEntries
语法导向操作
ExportEntries 不接受参数,返回一个包含 ExportEntry
Records 的 列表 。它在以下产生式上分段定义:
Module : [empty]
返回一个新的空 列表 。
ModuleItemList :
ModuleItemList
ModuleItem
设 entries1 为 ModuleItemList 的 ExportEntries 。
设 entries2 为 ModuleItem 的 ExportEntries 。
返回 entries1 和 entries2 的 列表连接 。
ModuleItem :
ImportDeclaration
StatementListItem
返回一个新的空 列表 。
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
设 module 为 ExportDeclaration 的 ModuleRequests
的唯一元素。
返回 ExportFromClause 以参数
module 的 ExportEntriesForModule 。
ExportDeclaration
:
export
NamedExports
;
返回 NamedExports
以参数 null 的 ExportEntriesForModule 。
ExportDeclaration
:
export
VariableStatement
设 entries 为一个新的空 列表 。
设 names 为 VariableStatement 的 BoundNames 。
对于 names 的每个元素 name ,执行
将 ExportEntry Record { [[ModuleRequest]] : null , [[ImportName]] : null , [[LocalName]] : name , [[ExportName]] : name } 追加到
entries 。
返回 entries 。
ExportDeclaration
:
export
Declaration
设 entries 为一个新的空 列表 。
设 names 为 Declaration 的 BoundNames 。
对于 names 的每个元素 name ,执行
将 ExportEntry Record { [[ModuleRequest]] : null , [[ImportName]] : null , [[LocalName]] : name , [[ExportName]] : name } 追加到
entries 。
返回 entries 。
ExportDeclaration
:
export
default
HoistableDeclaration
设 names 为 HoistableDeclaration 的
BoundNames 。
设 localName 为 names 的唯一元素。
返回一个 列表 ,其唯一元素是一个新的
ExportEntry Record { [[ModuleRequest]] : null , [[ImportName]] : null , [[LocalName]] : localName , [[ExportName]] : "default" }。
ExportDeclaration
:
export
default
ClassDeclaration
设 names 为 ClassDeclaration 的 BoundNames 。
设 localName 为 names 的唯一元素。
返回一个 列表 ,其唯一元素是一个新的
ExportEntry Record { [[ModuleRequest]] : null , [[ImportName]] : null , [[LocalName]] : localName , [[ExportName]] : "default" }。
ExportDeclaration
:
export
default
AssignmentExpression
;
设 entry 为 ExportEntry Record { [[ModuleRequest]] : null , [[ImportName]] : null , [[LocalName]] : "*default*" , [[ExportName]] : "default" }。
返回 « entry »。
注
"*default*" 在本规范中用作匿名默认导出值的合成名称。详见 此注释 。
16.2.3.5 静态语义:ExportEntriesForModule
语法导向操作
ExportEntriesForModule 接受参数 module (一个 ModuleRequest Record 或
null )并返回一个包含 ExportEntry
Records 的 列表 。它在以下产生式上分段定义:
ExportFromClause
: *
设 entry 为 ExportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : all-but-default , [[LocalName]] : null , [[ExportName]] : null }。
返回 « entry »。
ExportFromClause
:
*
as
ModuleExportName
设 exportName 为 ModuleExportName 的 StringValue 。
设 entry 为 ExportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : all , [[LocalName]] : null , [[ExportName]] : exportName }。
返回 « entry »。
NamedExports :
{
}
返回一个新的空 列表 。
ExportsList :
ExportsList
,
ExportSpecifier
设 specs1 为 ExportsList 以参数 module 的
ExportEntriesForModule 。
设 specs2 为 ExportSpecifier 以参数
module 的 ExportEntriesForModule 。
返回 specs1 和 specs2 的 列表连接 。
ExportSpecifier
: ModuleExportName
设 sourceName 为 ModuleExportName 的 StringValue 。
如果 module 是 null ,那么
设 localName 为 sourceName 。
设 importName 为 null 。
否则,
设 localName 为 null 。
设 importName 为 sourceName 。
返回一个 列表 ,其唯一元素是一个新的
ExportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : importName , [[LocalName]] : localName , [[ExportName]] : sourceName }。
ExportSpecifier
:
ModuleExportName
as
ModuleExportName
设 sourceName 为第一个 ModuleExportName 的 StringValue 。
设 exportName 为第二个 ModuleExportName 的 StringValue 。
如果 module 是 null ,那么
设 localName 为 sourceName 。
设 importName 为 null 。
否则,
设 localName 为 null 。
设 importName 为 sourceName 。
返回一个 列表 ,其唯一元素是一个新的
ExportEntry Record { [[ModuleRequest]] : module , [[ImportName]] : importName , [[LocalName]] : localName , [[ExportName]] : exportName }。
16.2.3.6 静态语义:ReferencedBindings
语法导向操作
ReferencedBindings 不接受参数,返回一个包含 解析节点 的 列表 。它在以下产生式上分段定义:
NamedExports :
{
}
返回一个新的空 列表 。
ExportsList :
ExportsList
,
ExportSpecifier
设 names1 为 ExportsList 的 ReferencedBindings 。
设 names2 为 ExportSpecifier 的 ReferencedBindings 。
返回 names1 和 names2 的 列表连接 。
ExportSpecifier
:
ModuleExportName
as
ModuleExportName
返回第一个 ModuleExportName 的 ReferencedBindings 。
ModuleExportName
: IdentifierName
返回一个 列表 ,其唯一元素是
IdentifierName 。
ModuleExportName
: StringLiteral
返回一个 列表 ,其唯一元素是
StringLiteral 。
16.2.3.7 运行时语义:Evaluation
ExportDeclaration
:
export
ExportFromClause
FromClause
WithClause opt
;
export
NamedExports
;
返回 empty 。
ExportDeclaration
:
export
VariableStatement
返回 ? VariableStatement 的 Evaluation 。
ExportDeclaration
:
export
Declaration
返回 ? Declaration 的 Evaluation 。
ExportDeclaration
:
export
default
HoistableDeclaration
返回 ? HoistableDeclaration 的
Evaluation 。
ExportDeclaration
:
export
default
ClassDeclaration
设 value 为 ? ClassDeclaration 的 BindingClassDeclarationEvaluation 。
设 className 为 ClassDeclaration 的 BoundNames 的唯一元素。
如果 className 是 "*default*" ,那么
设 env 为 正在运行的执行上下文 的
LexicalEnvironment。
执行 ? InitializeBoundName ("*default*" ,
value , env )。
返回 empty 。
ExportDeclaration
:
export
default
AssignmentExpression
;
如果 IsAnonymousFunctionDefinition (AssignmentExpression ) 是
true ,那么
设 value 为 ? AssignmentExpression
以参数 "default" 的 NamedEvaluation 。
否则,
设 rhs 为 ? AssignmentExpression
的 Evaluation 。
设 value 为 ? GetValue (rhs )。
设 env 为 正在运行的执行上下文 的
LexicalEnvironment。
执行 ? InitializeBoundName ("*default*" ,
value , env )。
返回 empty 。
17 错误处理和语言扩展
实现必须在评估相关的 ECMAScript 语言结构时报告大部分错误。早期错误 是可以在评估包含错误的 Script 中的任何结构之前检测和报告的错误。早期错误 的存在会阻止结构的评估。实现必须在 ParseScript 中解析 Script 时报告 Script 中的 早期错误 。Module 中的 早期错误 在 Module 将要被评估的时候报告,并且 Module 永远不会被初始化。eval 代码中的 早期错误 在调用 eval 时报告,并阻止 eval
代码的评估。所有不是 早期错误 的错误都是运行时错误。
实现必须将本规范的"静态语义:早期错误"子条款中列出的任何条件的出现报告为 早期错误 。
即使编译器可以证明结构在任何情况下都不能无错误地执行,实现也不应将其他类型的错误视为 早期错误 。实现可以在这种情况下发出早期警告,但它不应该在相关结构实际执行之前报告错误。
实现应按规定报告所有错误,除了以下情况:
除了在 17.1 中的限制外,宿主 或实现可以扩展 Script 语法、Module 语法以及正则表达式模式或标志语法。为了允许这一点,所有被允许抛出
SyntaxError 的操作(如调用 eval、使用正则表达式字面量或使用 Function 或 RegExp 构造器 )都被允许表现出 宿主定义的 行为,而不是在遇到脚本语法或正则表达式模式或标志语法的 宿主定义的 扩展时抛出
SyntaxError 。
除了在 17.1 中的限制外,宿主 或实现可以提供超出本规范中描述的附加类型、值、对象、属性和函数。这可能导致结构(如在全局作用域中查找变量)具有
宿主定义的 行为,而不是抛出错误(如 ReferenceError )。
17.1 禁止的扩展
实现不得以以下方式扩展本规范:
18 ECMAScript 标准内置对象
每当 ECMAScript Script 或 Module 开始执行时,都有某些内置对象可用。其中,全局对象 是执行程序的全局环境的一部分。其他对象可以作为 全局对象 的初始属性访问,或者作为可访问的内置对象的属性间接访问。
除非另有规定,可作为函数调用的内置对象是内置 函数对象 ,具有 10.3 中描述的特性。除非另有规定,内置对象的 [[Extensible]] 内部插槽最初具有值 true 。每个内置 函数对象 都有一个 [[Realm]] 内部插槽,其值是对象最初为其创建的 境界 的 Realm Record 。
许多内置对象都是函数:它们可以用参数调用。其中一些还是 构造器 :它们是用于与 new
操作符一起使用的函数。对于每个内置函数,本规范描述了该函数所需的参数和该 函数对象 的属性。对于每个内置 构造器 ,本规范还描述了该 构造器 的原型对象的属性以及调用该 构造器 的 new 表达式返回的特定对象实例的属性。
除非在特定函数的描述中另有规定,如果内置函数或 构造器 给定的参数少于函数指定要求的参数,该函数或 构造器 的行为应完全如同已给定了足够的附加参数,每个这样的参数都是
undefined 值。这样的缺失参数被认为是"不存在的",并且可以通过规范算法以这种方式识别。在特定函数的描述中,术语"this
值"和"NewTarget"具有 10.3 中给出的含义。
除非在特定函数的描述中另有规定,如果所描述的内置函数或 构造器 给定的参数比函数指定允许的更多,则额外的参数由调用评估然后被函数忽略。但是,实现可以定义与这些参数相关的实现特定行为,只要该行为不是简单基于额外参数存在而抛出
TypeError 异常。
注 1
鼓励向内置函数集添加附加功能的实现通过添加新函数而不是向现有函数添加新参数来实现。
除非另有规定,每个内置函数和每个内置 构造器 都将 Function 原型对象 作为其 [[Prototype]] 内部插槽的值,该对象是表达式 Function.prototype(20.2.3 )的初始值。
除非另有规定,每个内置原型对象都将 Object 原型对象 作为其 [[Prototype]] 内部插槽的值,该对象是表达式 Object.prototype(20.1.3 )的初始值,除了 Object 原型对象 本身。
如果本规范通过算法步骤定义内置 构造器 的行为,那么这就是它在 [[Call]] 和 [[Construct]] 目的上的行为。如果这样的算法需要区分这两种情况,它会检查 NewTarget 是否为
undefined ,这表示 [[Call]] 调用。
未被标识为 构造器 的内置 函数对象 不实现 [[Construct]] 内部方法,除非在特定函数的描述中另有规定。
不是 构造器 的内置 函数对象 没有
"prototype" 属性,除非在特定函数的描述中另有规定。
本规范中定义的每个内置函数都是通过调用 CreateBuiltinFunction 抽象操作(10.3.4 )创建的。length 和 name
参数的值是 "length" 和 "name" 属性的初始值,如下所述。prefix
参数的值也在下面类似地讨论。
每个内置 函数对象 ,包括
构造器 ,都有一个
"length" 属性,其值是非负的 整数 。除非另有规定,此值是函数描述的子条款标题中显示的必需参数数。可选参数和剩余参数不包括在参数计数中。
注 2
例如,Array 原型对象 的
"map" 属性的初始值的 函数对象 在子条款标题"Array.prototype.map (callback [ ,
thisArg])"下描述,显示了两个命名参数 callback 和 thisArg,后者是可选的;因此该 函数对象 的 "length"
属性的值是 1 𝔽 。
除非另有规定,内置 函数对象 的 "length" 属性具有特性 { [[Writable]] : false , [[Enumerable]] :
false , [[Configurable]] : true }。
每个内置 函数对象 ,包括
构造器 ,都有一个
"name" 属性,其值 是一个字符串 。除非另有规定,此值是本规范中给予函数的名称。被标识为匿名函数的函数使用空字符串作为
"name" 属性的值。对于被指定为对象属性的函数,名称值是用于访问函数的 属性名 字符串。被指定为内置属性的 get 或 set 访问器函数的函数在调用
CreateBuiltinFunction 时将
"get" 或 "set" (分别)传递给 prefix 参数。
对于 属性键 是 Symbol
值的每个内置函数,"name" 属性的值被显式指定。如果这样的显式指定值以前缀 "get " 或 "set
" 开头,并且为其指定的函数是内置属性的 get 或 set 访问器函数,则不带前缀的值传递给 name 参数,并且值
"get" 或 "set" (分别)在调用 CreateBuiltinFunction 时传递给
prefix 参数。
除非另有规定,内置 函数对象 的 "name" 属性具有特性 { [[Writable]] : false , [[Enumerable]] :
false , [[Configurable]] : true }。
条款 19 到
28 以及附录
B.2 中描述的每个其他 数据属性 都具有特性 { [[Writable]] : true , [[Enumerable]] :
false , [[Configurable]] : true },除非另有规定。
条款 19 到
28 以及附录
B.2 中描述的每个 访问器属性 都具有特性 { [[Enumerable]] : false , [[Configurable]] : true },除非另有规定。如果只描述了 get 访问器函数,则 set
访问器函数是默认值 undefined 。如果只描述了 set 访问器,则 get 访问器是默认值 undefined 。
19 全局对象
全局对象 :
在控制进入任何 执行上下文 之前创建。
没有 [[Construct]] 内部方法;它不能作为 构造器 与 new 操作符一起使用。
没有 [[Call]] 内部方法;它不能作为函数调用。
有一个 [[Prototype]] 内部插槽,其值是 宿主定义的 。
除了本规范中定义的属性外,还可能有 宿主定义的 属性。这可能包括一个值为全局对象本身的属性。
19.1 全局对象的值属性
19.1.1 globalThis
Realm Record
realm 中 全局对象 的 "globalThis" 属性的初始值是
realm .[[GlobalEnv]] .[[GlobalThisValue]] 。
此属性具有特性 { [[Writable]] :
true , [[Enumerable]] : false , [[Configurable]] : true }。
19.1.2 Infinity
Infinity 的值是 +∞ 𝔽 (见 6.1.6.1 )。此属性具有特性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false }。
19.1.3 NaN
NaN 的值是 NaN (见 6.1.6.1 )。此属性具有特性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false }。
19.1.4 undefined
undefined 的值是 undefined (见 6.1.1 )。此属性具有特性 {
[[Writable]] : false ,
[[Enumerable]] : false , [[Configurable]] : false }。
19.2 全局对象的函数属性
19.2.1 eval ( x )
此函数是 %eval% 内置对象。
当被调用时执行以下步骤:
返回 ? PerformEval (x ,
false , false )。
19.2.1.1 PerformEval ( x , strictCaller ,
direct )
抽象操作 PerformEval 接受参数 x (一个 ECMAScript
语言值 )、strictCaller (一个布尔值)和 direct (一个布尔值),返回一个包含
ECMAScript 语言值 的 正常完成 或一个 抛出完成 。当被调用时执行以下步骤:
断言 :如果
direct 是 false ,那么 strictCaller 也是
false 。
如果 x 不是字符串 ,返回
x 。
设 evalRealm 为 当前 Realm Record 。
注:在 直接
eval 的情况下,evalRealm 是 eval 调用者和
eval 函数本身的 境界 。
执行 ? HostEnsureCanCompileStrings (evalRealm ,
« », x , direct )。
设 inFunction 为 false 。
设 inMethod 为 false 。
设 inDerivedConstructor 为 false 。
设 inClassFieldInitializer 为 false 。
如果 direct 是 true ,那么
设 thisEnvRec 为 GetThisEnvironment ()。
如果 thisEnvRec 是一个 函数环境记录 ,那么
设 F 为 thisEnvRec .[[FunctionObject]] 。
设 inFunction 为 true 。
设 inMethod 为 thisEnvRec .HasSuperBinding()。
如果 F .[[ConstructorKind]] 是
derived ,设 inDerivedConstructor 为
true 。
设 classFieldInitializerName 为 F .[[ClassFieldInitializerName]] 。
如果 classFieldInitializerName 不是
empty ,设 inClassFieldInitializer 为
true 。
以 实现定义的 顺序执行以下子步骤,可能交替进行解析和错误检测:
设 script 为 ParseText (x , Script )。
如果 script 是一个错误的 列表 ,抛出
SyntaxError 异常。
如果 script Contains
ScriptBody
是 false ,返回 undefined 。
设 body 为 script 的 ScriptBody 。
如果 inFunction 是 false 且 body
Contains
NewTarget ,
抛出 SyntaxError 异常。
如果 inMethod 是 false 且 body
Contains
SuperProperty ,抛出
SyntaxError 异常。
如果 inDerivedConstructor 是 false 且
body Contains
SuperCall ,
抛出 SyntaxError 异常。
如果 inClassFieldInitializer 是 true 且
body 的 ContainsArguments
是 true ,抛出 SyntaxError 异常。
如果 strictCaller 是 true ,设 strictEval 为
true 。
否则,设 strictEval 为 script 的 ScriptIsStrict 。
设 runningContext 为 正在运行的执行上下文 。
注:如果 direct 是 true ,runningContext
将是执行 直接
eval 的 执行上下文 。如果
direct 是 false ,runningContext 将是调用
eval 函数的 执行上下文 。
如果 direct 是 true ,那么
设 lexEnv 为 NewDeclarativeEnvironment (runningContext
的 LexicalEnvironment)。
设 varEnv 为 runningContext 的 VariableEnvironment。
设 privateEnv 为 runningContext 的 PrivateEnvironment。
否则,
设 lexEnv 为 NewDeclarativeEnvironment (evalRealm .[[GlobalEnv]] )。
设 varEnv 为 evalRealm .[[GlobalEnv]] 。
设 privateEnv 为 null 。
如果 strictEval 是 true ,设 varEnv 为
lexEnv 。
如果 runningContext 尚未挂起,挂起 runningContext 。
设 evalContext 为一个新的 ECMAScript
代码执行上下文 。
设 evalContext 的 Function 为 null 。
设 evalContext 的 Realm 为 evalRealm 。
设 evalContext 的 ScriptOrModule 为 runningContext 的
ScriptOrModule。
设 evalContext 的 VariableEnvironment 为 varEnv 。
设 evalContext 的 LexicalEnvironment 为 lexEnv 。
设 evalContext 的 PrivateEnvironment 为 privateEnv 。
将 evalContext 推入 执行上下文栈 ;evalContext
现在是 正在运行的执行上下文 。
设 result 为 Completion (EvalDeclarationInstantiation (body ,
varEnv , lexEnv , privateEnv ,
strictEval ))。
如果 result 是一个 正常完成 ,那么
设 result 为 Completion (body
的 Evaluation )。
如果 result 是一个 正常完成 且
result .[[Value]] 是
empty ,那么
设 result 为 NormalCompletion (undefined )。
挂起 evalContext 并将其从 执行上下文栈 中移除。
恢复现在位于 执行上下文栈 顶部的上下文作为 正在运行的执行上下文 。
返回 ? result 。
注
如果调用上下文的代码或 eval 代码是 严格模式代码 ,那么 eval 代码不能在调用 eval
的调用上下文的变量环境中实例化变量或函数绑定。相反,这些绑定在只有 eval 代码可访问的新 VariableEnvironment 中实例化。由
let、const 或 class 声明引入的绑定总是在新的
LexicalEnvironment 中实例化。
19.2.1.2 HostEnsureCanCompileStrings ( calleeRealm ,
parameterStrings , bodyString , direct )
宿主定义的 抽象操作 HostEnsureCanCompileStrings 接受参数
calleeRealm (一个 Realm
Record )、parameterStrings (一个字符串的 列表 )、bodyString (一个字符串)和
direct (一个布尔值),返回一个包含 unused 的 正常完成 或一个 抛出完成 。它允许 宿主环境 阻止某些允许开发者将字符串解释和评估为 ECMAScript 代码的
ECMAScript 函数。
parameterStrings 表示在使用函数 构造器 之一时将连接在一起以构建参数列表的字符串。bodyString
表示函数体或传递给 eval 调用的字符串。direct 表示评估是否是 直接 eval 。
HostEnsureCanCompileStrings 的默认实现是返回 NormalCompletion (unused )。
19.2.1.3 EvalDeclarationInstantiation ( body ,
varEnv , lexEnv , privateEnv , strict )
抽象操作 EvalDeclarationInstantiation 接受参数 body (一个 ScriptBody 解析节点 )、varEnv (一个 环境记录 )、lexEnv (一个 声明式环境记录 )、privateEnv (一个
私有环境记录 或 null )和
strict (一个布尔值),返回一个包含 unused 的 正常完成 或一个 抛出完成 。当被调用时执行以下步骤:
设 varNames 为 body 的 VarDeclaredNames 。
设 varDeclarations 为 body 的 VarScopedDeclarations 。
如果 strict 是 false ,那么
如果 varEnv 是一个 全局环境记录 ,那么
对于 varNames 的每个元素 name ,执行
如果 HasLexicalDeclaration (varEnv ,
name ) 是 true ,抛出
SyntaxError 异常。
注:eval 不会创建被全局词法声明遮蔽的全局 var 声明。
设 thisEnv 为 lexEnv 。
断言 :以下循环将终止。
重复,当 thisEnv 和 varEnv 不是同一个 环境记录 时,
如果 thisEnv 不是对象
环境记录 ,那么
注:with 语句的环境不能包含任何词法声明,因此不需要检查 var/let 提升冲突。
对于 varNames 的每个元素 name ,执行
如果
! thisEnv .HasBinding(name )
是 true ,那么
抛出 SyntaxError 异常。
注:附录 B.3.4
为上述步骤定义了替代语义。
注:直接
eval 不会将 var 声明提升到同名的词法声明之上。
设 thisEnv 为 thisEnv .[[OuterEnv]] 。
设 privateIdentifiers 为一个新的空 列表 。
设 pointer 为 privateEnv 。
重复,当 pointer 不是 null 时,
对于 pointer .[[Names]] 的每个 私有名称
binding ,执行
如果 privateIdentifiers 不包含
binding .[[Description]] ,将
binding .[[Description]] 添加到
privateIdentifiers 。
设 pointer 为 pointer .[[OuterPrivateEnvironment]] 。
如果 body 以参数 privateIdentifiers 的 AllPrivateIdentifiersValid
是 false ,抛出 SyntaxError 异常。
设 functionsToInitialize 为一个新的空 列表 。
设 declaredFunctionNames 为一个新的空 列表 。
对于 varDeclarations 的每个元素 d ,以反向 列表 顺序,执行
如果 d 不是 VariableDeclaration 、ForBinding 或
BindingIdentifier ,那么
断言 :d 是 FunctionDeclaration 、GeneratorDeclaration 、AsyncFunctionDeclaration
或 AsyncGeneratorDeclaration 。
注:如果同一个名称有多个函数声明,使用最后一个声明。
设 fn 为 d 的 BoundNames
的唯一元素。
如果 declaredFunctionNames 不包含 fn ,那么
如果 varEnv 是一个 全局环境记录 ,那么
设 fnDefinable 为 ? CanDeclareGlobalFunction (varEnv ,
fn )。
如果 fnDefinable 是
false ,抛出
TypeError 异常。
将 fn 添加到 declaredFunctionNames 。
将 d 插入为 functionsToInitialize 的第一个元素。
设 declaredVarNames 为一个新的空 列表 。
对于 varDeclarations 的每个元素 d ,执行
如果 d 是 VariableDeclaration 、ForBinding 或
BindingIdentifier ,那么
对于 d 的 BoundNames
的每个字符串 vn ,执行
如果 declaredFunctionNames 不包含 vn ,那么
如果 varEnv 是一个 全局环境记录 ,那么
设 vnDefinable 为
? CanDeclareGlobalVar (varEnv ,
vn )。
如果 vnDefinable 是
false ,抛出
TypeError 异常。
如果 declaredVarNames 不包含 vn ,那么
将 vn 添加到
declaredVarNames 。
注:附录 B.3.2.3
在此处添加额外的步骤。
注:除非 varEnv 是一个
全局环境记录 且 全局对象 是一个 Proxy
异质对象 ,否则在此算法步骤之后不会发生异常终止。
设 lexDeclarations 为 body 的 LexicallyScopedDeclarations 。
对于 lexDeclarations 的每个元素 d ,执行
注:词法声明的名称仅在此处实例化但不初始化。
对于 d 的 BoundNames
的每个元素 dn ,执行
如果 d 的 IsConstantDeclaration
是 true ,那么
执行
? lexEnv .CreateImmutableBinding(dn ,
true )。
否则,
执行
? lexEnv .CreateMutableBinding(dn ,
false )。
对于 functionsToInitialize 的每个 解析节点
f ,执行
设 fn 为 f 的 BoundNames
的唯一元素。
设 fo 为 f 以参数 lexEnv 和 privateEnv
的 InstantiateFunctionObject 。
如果 varEnv 是一个 全局环境记录 ,那么
执行 ? CreateGlobalFunctionBinding (varEnv ,
fn , fo , true )。
否则,
设 bindingExists 为
! varEnv .HasBinding(fn )。
如果 bindingExists 是 false ,那么
注:由于步骤 14
之前的验证,以下调用不能返回 异常完成 。
执行
! varEnv .CreateMutableBinding(fn ,
true )。
执行
! varEnv .InitializeBinding(fn ,
fo )。
否则,
执行
! varEnv .SetMutableBinding(fn ,
fo , false )。
对于 declaredVarNames 的每个字符串 vn ,执行
如果 varEnv 是一个 全局环境记录 ,那么
执行 ? CreateGlobalVarBinding (varEnv ,
vn , true )。
否则,
设 bindingExists 为
! varEnv .HasBinding(vn )。
如果 bindingExists 是 false ,那么
注:由于步骤 14
之前的验证,以下调用不能返回 异常完成 。
执行
! varEnv .CreateMutableBinding(vn ,
true )。
执行
! varEnv .InitializeBinding(vn ,
undefined )。
返回 unused 。
注
19.2.2 isFinite ( number )
此函数是 %isFinite% 内置对象。
当被调用时执行以下步骤:
设 num 为 ? ToNumber (number )。
如果 num 不是 有限的 ,返回 false 。
否则,返回 true 。
19.2.3 isNaN ( number )
此函数是 %isNaN% 内置对象。
当被调用时执行以下步骤:
设 num 为 ? ToNumber (number )。
如果 num 是 NaN ,返回 true 。
否则,返回 false 。
注
ECMAScript 代码测试值 X 是否为 NaN 的可靠方法是使用形式为
X !== X 的表达式。当且仅当 X 是 NaN 时,结果将是
true 。
19.2.4 parseFloat ( string )
此函数根据对 string 参数内容作为十进制字面量的解释产生一个数值。
它是 %parseFloat% 内置对象。
当被调用时执行以下步骤:
设 inputString 为 ? ToString (string )。
设 trimmedString 为 ! TrimString (inputString ,
start )。
设 trimmed 为 StringToCodePoints (trimmedString )。
设 trimmedPrefix 为满足 StrDecimalLiteral 语法的
trimmed 的最长前缀,可能是 trimmed 本身。如果没有这样的前缀,返回 NaN 。
设 parsedNumber 为 ParseText (trimmedPrefix , StrDecimalLiteral )。
断言 :
parsedNumber 是一个 解析节点 。
返回 parsedNumber 的 StringNumericValue 。
注
此函数可能仅将 string 的前导部分解释为数值;它忽略任何不能解释为十进制字面量表示法一部分的代码单元,并且不会给出任何此类代码单元被忽略的指示。
19.2.5 parseInt ( string , radix )
此函数根据指定的 radix 对 string 内容的解释产生一个 整数 。忽略 string 中的前导空白。如果
radix 强制转换为 0(例如当它是 undefined 时),则假设为 10,除非数字表示以
"0x" 或 "0X" 开头,在这种情况下假设为 16。如果 radix 是
16,数字表示可以可选地以 "0x" 或 "0X" 开头。
它是 %parseInt% 内置对象。
当被调用时执行以下步骤:
设 inputString 为 ? ToString (string )。
设 S 为 ! TrimString (inputString ,
start )。
设 sign 为 1。
如果 S 不为空且 S 的第一个代码单元是代码单元 0x002D(连字符减号),设 sign 为 -1。
如果 S 不为空且 S 的第一个代码单元是代码单元 0x002B(加号)或代码单元 0x002D(连字符减号),设
S 为 S 从索引 1 开始的 子字符串 。
设 R 为 ℝ (?
ToInt32 (radix ))。
设 stripPrefix 为 true 。
如果 R ≠ 0,那么
如果 R < 2 或 R > 36,返回 NaN 。
如果 R ≠ 16,设 stripPrefix 为 false 。
否则,
设 R 为 10。
如果 stripPrefix 是 true ,那么
如果 S 的长度至少为 2 且 S 的前两个代码单元是 "0x" 或
"0X" ,那么
设 S 为 S 从索引 2 开始的 子字符串 。
设 R 为 16。
如果 S 包含不是基数-R 数字的代码单元,设 end 为 S
中第一个这样的代码单元的索引;否则,设 end 为 S 的长度。
设 Z 为 S 从 0 到 end 的 子字符串 。
如果 Z 为空,返回 NaN 。
设 mathInt 为以基数-R 表示法表示的 Z 所表示的 整数 值,使用字母 A 到
Z 和 a 到 z 表示值 10 到 35 的数字。(但是,如果 R = 10 且 Z
包含超过 20 个有效数字,实现可以选择将第 20 个之后的每个有效数字替换为 0 数字;如果 R 不是 2、4、8、10、16 或 32 之一,那么
mathInt 可能是一个 实现近似的 整数 ,表示 Z
在基数-R 表示法中表示的 整数 值。)
如果 mathInt = 0,那么
如果 sign = -1,返回 -0 𝔽 。
返回 +0 𝔽 。
返回 𝔽 (sign ×
mathInt )。
注
此函数可能仅将 string 的前导部分解释为 整数 值;它忽略任何不能解释为 整数 表示法一部分的代码单元,并且不会给出任何此类代码单元被忽略的指示。
19.2.6 URI 处理函数
统一资源标识符(URI)是标识资源(例如网页或文件)和访问它们的传输协议(例如 HTTP 或 FTP)的字符串。ECMAScript 语言本身不提供对使用 URI
的任何支持,除了本节中描述的编码和解码 URI 的函数。encodeURI 和 decodeURI 旨在与完整的 URI
一起工作;它们假设任何保留字符都旨在具有特殊含义(例如,作为分隔符),因此不进行编码。encodeURIComponent 和
decodeURIComponent 旨在与 URI 的各个组件一起工作;它们假设任何保留字符表示文本,必须编码以避免在组件是完整 URI 的一部分时具有特殊含义。
注 1
保留字符集基于 RFC 2396,不反映更新的 RFC 3986 引入的更改。
注 2
许多 ECMAScript 实现提供操作网页的附加函数和方法;这些函数超出了本标准的范围。
19.2.6.1 decodeURI ( encodedURI )
此函数计算 URI 的新版本,其中每个可能由 encodeURI 函数引入的转义序列和 UTF-8 编码都被其表示的代码点的 UTF-16 编码替换。不可能由
encodeURI 引入的转义序列不被替换。
它是 %decodeURI% 内置对象。
当被调用时执行以下步骤:
设 uriString 为 ? ToString (encodedURI )。
设 preserveEscapeSet 为 ";/?:@&=+$,#" 。
返回 ? Decode (uriString ,
preserveEscapeSet )。
19.2.6.2 decodeURIComponent ( encodedURIComponent )
此函数计算 URI 的新版本,其中每个可能由 encodeURIComponent 函数引入的转义序列和 UTF-8 编码都被其表示的代码点的 UTF-16
编码替换。
它是 %decodeURIComponent% 内置对象。
当被调用时执行以下步骤:
设 componentString 为 ? ToString (encodedURIComponent )。
设 preserveEscapeSet 为空字符串。
返回 ? Decode (componentString ,
preserveEscapeSet )。
19.2.6.3 encodeURI ( uri )
此函数计算 UTF-16 编码(6.1.4 )URI
的新版本,其中某些代码点的每个实例都被表示代码点的 UTF-8 编码的一个、两个、三个或四个转义序列替换。
它是 %encodeURI% 内置对象。
当被调用时执行以下步骤:
设 uriString 为 ? ToString (uri )。
设 extraUnescaped 为 ";/?:@&=+$,#" 。
返回 ? Encode (uriString ,
extraUnescaped )。
19.2.6.4 encodeURIComponent ( uriComponent )
此函数计算 UTF-16 编码(6.1.4 )URI
的新版本,其中某些代码点的每个实例都被表示代码点的 UTF-8 编码的一个、两个、三个或四个转义序列替换。
它是 %encodeURIComponent% 内置对象。
当被调用时执行以下步骤:
设 componentString 为 ? ToString (uriComponent )。
设 extraUnescaped 为空字符串。
返回 ? Encode (componentString ,
extraUnescaped )。
19.2.6.5 Encode ( string , extraUnescaped )
抽象操作 Encode 接受参数 string (一个字符串)和 extraUnescaped (一个字符串),返回一个包含字符串的
正常完成 或一个 抛出完成 。它执行 URI 编码和转义,将
string 解释为 6.1.4
中描述的 UTF-16 编码代码点序列。如果字符在 RFC 2396 中被标识为未保留的或出现在 extraUnescaped
中,则不进行转义。当被调用时执行以下步骤:
设 len 为 string 的长度。
设 R 为空字符串。
设 alwaysUnescaped 为 ASCII 单词字符 和
"-.!~*'()" 的 字符串连接 。
设 unescapedSet 为 alwaysUnescaped 和 extraUnescaped 的
字符串连接 。
设 k 为 0。
重复,当 k < len 时,
设 C 为 string 中索引 k 处的代码单元。
如果 unescapedSet 包含 C ,那么
设 k 为 k + 1。
设 R 为 R 和 C 的 字符串连接 。
否则,
设 cp 为 CodePointAt (string ,
k )。
如果 cp .[[IsUnpairedSurrogate]] 是
true ,抛出 URIError 异常。
设 k 为 k + cp .[[CodeUnitCount]] 。
设 Octets 为通过对 cp .[[CodePoint]] 应用 UTF-8 变换得到的八位字节的 列表 。
对于 Octets 的每个元素 octet ,执行
设 hex 为 octet 的字符串表示,格式化为大写十六进制数。
设 R 为 R 、"%" 和
StringPad (hex ,
2, "0" , start ) 的
字符串连接 。
返回 R 。
注
因为百分号编码用于表示单个八位字节,所以单个代码点可能表示为多个连续的转义序列(其 8 位 UTF-8 代码单元的每一个对应一个)。
19.2.6.6 Decode ( string ,
preserveEscapeSet )
抽象操作 Decode 接受参数 string (一个字符串)和 preserveEscapeSet (一个字符串),返回一个包含字符串的
正常完成 或一个 抛出完成 。它执行 URI
反转义和解码,保留与 preserveEscapeSet 中的基本拉丁字符对应的任何转义序列。当被调用时执行以下步骤:
设 len 为 string 的长度。
设 R 为空字符串。
设 k 为 0。
重复,当 k < len 时,
设 C 为 string 中索引 k 处的代码单元。
设 S 为 C 。
如果 C 是代码单元 0x0025(百分号),那么
如果 k + 3 > len ,抛出
URIError 异常。
设 escape 为 string 从 k 到
k + 3 的 子字符串 。
设 B 为 ParseHexOctet (string ,
k + 1)。
如果 B 不是一个 整数 ,抛出
URIError 异常。
设 k 为 k + 2。
设 n 为 B 中前导 1 位的数量。
如果 n = 0,那么
设 asciiChar 为数值为 B 的代码单元。
如果 preserveEscapeSet 包含 asciiChar ,设
S 为 escape 。否则,设 S 为
asciiChar 。
否则,
如果 n = 1 或 n > 4,抛出
URIError 异常。
设 Octets 为 « B »。
设 j 为 1。
重复,当 j < n 时,
设 k 为 k + 1。
如果 k + 3 > len ,抛出
URIError 异常。
如果 string 中索引 k 处的代码单元不是代码单元
0x0025(百分号),抛出 URIError 异常。
设 continuationByte 为 ParseHexOctet (string ,
k + 1)。
如果 continuationByte 不是一个 整数 ,抛出
URIError 异常。
将 continuationByte 添加到 Octets 。
设 k 为 k + 2。
设 j 为 j + 1。
断言 :Octets
的长度是 n 。
如果 Octets 不包含 Unicode 代码点的有效 UTF-8 编码,抛出
URIError 异常。
设 V 为通过对 Octets 应用 UTF-8
变换获得的代码点,即从八位字节的 列表 到
21 位值。
设 S 为 UTF16EncodeCodePoint (V )。
设 R 为 R 和 S 的 字符串连接 。
设 k 为 k + 1。
返回 R 。
注
RFC 3629 禁止解码无效的 UTF-8 八位字节序列。例如,无效序列 0xC0 0x80 不得解码为代码单元 0x0000。Decode
算法的实现在遇到此类无效序列时必须抛出 URIError 。
19.2.6.7 ParseHexOctet ( string , position
)
抽象操作 ParseHexOctet 接受参数 string (一个字符串)和 position (一个非负 整数 ),返回一个非负 整数 或一个非空的
SyntaxError 对象的 列表 。它解析
string 中指定 position 处的两个十六进制字符序列为一个无符号 8 位 整数 。当被调用时执行以下步骤:
设 len 为 string 的长度。
断言 :
position + 2 ≤ len 。
设 hexDigits 为 string 从 position 到
position + 2 的 子字符串 。
设 parseResult 为 ParseText (hexDigits , HexDigits [~Sep] )。
如果 parseResult 不是一个 解析节点 ,返回
parseResult 。
设 n 为 parseResult 的 MV。
断言 :
n 在从 0 到 255 的 闭区间 内。
返回 n 。
19.3 全局对象的构造器属性
19.3.1 AggregateError ( . . . )
参见 20.5.7.1 。
19.3.2 Array ( . . . )
参见 23.1.1 。
19.3.3 ArrayBuffer ( . . . )
参见 25.1.4 。
19.3.4 BigInt ( . . . )
参见 21.2.1 。
19.3.5 BigInt64Array ( . . . )
参见 23.2.5 。
19.3.6 BigUint64Array ( . . . )
参见 23.2.5 。
19.3.7 Boolean ( . . . )
参见 20.3.1 。
19.3.8 DataView ( . . . )
参见 25.3.2 。
19.3.9 Date ( . . . )
参见 21.4.2 。
19.3.10 Error ( . . . )
参见 20.5.1 。
19.3.11 EvalError ( . . . )
参见 20.5.5.1 。
19.3.12 FinalizationRegistry ( . . . )
参见 26.2.1 。
19.3.13 Float16Array ( . . . )
参见 23.2.5 。
19.3.14 Float32Array ( . . . )
参见 23.2.5 。
19.3.15 Float64Array ( . . . )
参见 23.2.5 。
19.3.16 Function ( . . . )
参见 20.2.1 。
19.3.17 Int8Array ( . . . )
参见 23.2.5 。
19.3.18 Int16Array ( . . . )
参见 23.2.5 。
19.3.19 Int32Array ( . . . )
参见 23.2.5 。
19.3.20 Iterator ( . . . )
参见 27.1.3.1 。
19.3.21 Map ( . . . )
参见 24.1.1 。
19.3.22 Number ( . . . )
参见 21.1.1 。
19.3.23 Object ( . . . )
参见 20.1.1 。
19.3.24 Promise ( . . . )
参见 27.2.3 。
19.3.25 Proxy ( . . . )
参见 28.2.1 。
19.3.26 RangeError ( . . . )
参见 20.5.5.2 。
19.3.27 ReferenceError ( . . . )
参见 20.5.5.3 。
19.3.28 RegExp ( . . . )
参见 22.2.4 。
19.3.29 Set ( . . . )
参见 24.2.2 。
19.3.30 SharedArrayBuffer ( . . . )
参见 25.2.3 。
19.3.31 String ( . . . )
参见 22.1.1 。
19.3.32 Symbol ( . . . )
参见 20.4.1 。
19.3.33 SyntaxError ( . . . )
参见 20.5.5.4 。
19.3.34 TypeError ( . . . )
参见 20.5.5.5 。
19.3.35 Uint8Array ( . . . )
参见 23.2.5 。
19.3.36 Uint8ClampedArray ( . . . )
参见 23.2.5 。
19.3.37 Uint16Array ( . . . )
参见 23.2.5 。
19.3.38 Uint32Array ( . . . )
参见 23.2.5 。
19.3.39 URIError ( . . . )
参见 20.5.5.6 。
19.3.40 WeakMap ( . . . )
参见 24.3.1 。
19.3.41 WeakRef ( . . . )
参见 26.1.1 。
19.3.42 WeakSet ( . . . )
参见 24.4 。
19.4 全局对象的其他属性
19.4.1 Atomics
参见 25.4 。
19.4.2 JSON
参见 25.5 。
19.4.3 Math
参见 21.3 。
19.4.4 Reflect
参见 28.1 。
20 基础对象
20.1 Object 对象
20.1.1 Object 构造器
Object 构造器 :
是 %Object% 。
是 全局对象 的 "Object" 属性的初始值。
当作为 构造器 调用时,创建一个新的 普通对象 。
当作为函数而不是 构造器 调用时,执行类型转换。
可以用作类定义的 extends 子句的值。
20.1.1.1 Object ( [ value ] )
此函数在被调用时执行以下步骤:
如果 NewTarget 既不是 undefined 也不是 活动函数对象 ,那么
返回 ? OrdinaryCreateFromConstructor (NewTarget,
"%Object.prototype%" )。
如果 value 是 undefined 或 null ,返回
OrdinaryObjectCreate (%Object.prototype% )。
返回 ! ToObject (value )。
20.1.2 Object 构造器的属性
Object 构造器 :
20.1.2.1 Object.assign ( target ,
...sources )
此函数从一个或多个源对象复制所有可枚举自有属性的值到 target 对象。
当被调用时执行以下步骤:
设 to 为 ? ToObject (target )。
如果只传递了一个参数,返回 to 。
对于 sources 的每个元素 nextSource ,执行
如果 nextSource 既不是 undefined 也不是
null ,那么
设 from 为 ! ToObject (nextSource )。
设 keys 为 ? from .[[OwnPropertyKeys]] () 。
对于 keys 的每个元素 nextKey ,执行
设 desc 为 ? from .[[GetOwnProperty]] (nextKey )。
如果 desc 不是 undefined 且
desc .[[Enumerable]] 是
true ,那么
设 propValue 为 ? Get (from ,
nextKey )。
执行 ? Set (to ,
nextKey , propValue ,
true )。
返回 to 。
此函数的 "length" 属性是 2 𝔽 。
20.1.2.2 Object.create ( O , Properties )
此函数创建一个具有指定原型的新对象。
当被调用时执行以下步骤:
如果 O 不是一个对象 且 O 不是
null ,抛出 TypeError 异常。
设 obj 为 OrdinaryObjectCreate (O )。
如果 Properties 不是 undefined ,那么
返回 ? ObjectDefineProperties (obj ,
Properties )。
返回 obj 。
20.1.2.3 Object.defineProperties ( O ,
Properties )
此函数添加自有属性和/或更新对象现有自有属性的特性。
当被调用时执行以下步骤:
如果 O 不是一个对象 ,抛出
TypeError 异常。
返回 ? ObjectDefineProperties (O ,
Properties )。
20.1.2.3.1 ObjectDefineProperties ( O ,
Properties )
抽象操作 ObjectDefineProperties 接受参数 O (一个对象)和 Properties (一个 ECMAScript 语言值 ),返回一个包含对象的
正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
设 props 为 ? ToObject (Properties )。
设 keys 为 ? props .[[OwnPropertyKeys]] () 。
设 descriptors 为一个新的空 列表 。
对于 keys 的每个元素 nextKey ,执行
设 propDesc 为 ? props .[[GetOwnProperty]] (nextKey )。
如果 propDesc 不是 undefined 且
propDesc .[[Enumerable]] 是
true ,那么
设 descObj 为 ? Get (props ,
nextKey )。
设 desc 为 ? ToPropertyDescriptor (descObj )。
将 记录
{ [[Key]] : nextKey , [[Descriptor]] : desc }
追加到 descriptors 。
对于 descriptors 的每个元素 property ,执行
执行 ? DefinePropertyOrThrow (O ,
property .[[Key]] ,
property .[[Descriptor]] )。
返回 O 。
20.1.2.4 Object.defineProperty ( O , P ,
Attributes )
此函数添加一个自有属性和/或更新对象现有自有属性的特性。
当被调用时执行以下步骤:
如果 O 不是一个对象 ,抛出
TypeError 异常。
设 key 为 ? ToPropertyKey (P )。
设 desc 为 ? ToPropertyDescriptor (Attributes )。
执行 ? DefinePropertyOrThrow (O ,
key , desc )。
返回 O 。
20.1.2.5 Object.entries ( O )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 entryList 为 ? EnumerableOwnProperties (obj ,
key+value )。
返回 CreateArrayFromList (entryList )。
20.1.2.6 Object.freeze ( O )
此函数在被调用时执行以下步骤:
如果 O 不是一个对象 ,返回 O 。
设 status 为 ? SetIntegrityLevel (O ,
frozen )。
如果 status 是 false ,抛出 TypeError 异常。
返回 O 。
20.1.2.7 Object.fromEntries ( iterable )
此函数在被调用时执行以下步骤:
执行 ? RequireObjectCoercible (iterable )。
设 obj 为 OrdinaryObjectCreate (%Object.prototype% )。
断言 :
obj 是一个可扩展的 普通对象 ,没有自有属性。
设 closure 为一个新的 抽象闭包 ,参数为 (key ,
value ),捕获 obj ,当被调用时执行以下步骤:
设 propertyKey 为 ? ToPropertyKey (key )。
执行 ! CreateDataPropertyOrThrow (obj ,
propertyKey , value )。
返回 undefined 。
设 adder 为 CreateBuiltinFunction (closure ,
2, "" , « »)。
返回 ? AddEntriesFromIterable (obj ,
iterable , adder )。
注
为 adder 创建的函数永远不会直接被 ECMAScript 代码访问。
20.1.2.8 Object.getOwnPropertyDescriptor ( O ,
P )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 key 为 ? ToPropertyKey (P )。
设 desc 为 ? obj .[[GetOwnProperty]] (key )。
返回 FromPropertyDescriptor (desc )。
20.1.2.9 Object.getOwnPropertyDescriptors ( O )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 ownKeys 为 ? obj .[[OwnPropertyKeys]] () 。
设 descriptors 为 OrdinaryObjectCreate (%Object.prototype% )。
对于 ownKeys 的每个元素 key ,执行
设 desc 为 ? obj .[[GetOwnProperty]] (key )。
设 descriptor 为 FromPropertyDescriptor (desc )。
如果 descriptor 不是 undefined ,执行 ! CreateDataPropertyOrThrow (descriptors ,
key , descriptor )。
返回 descriptors 。
20.1.2.10 Object.getOwnPropertyNames ( O )
此函数在被调用时执行以下步骤:
返回 CreateArrayFromList (?
GetOwnPropertyKeys (O ,
string ))。
20.1.2.11 Object.getOwnPropertySymbols ( O )
此函数在被调用时执行以下步骤:
返回 CreateArrayFromList (?
GetOwnPropertyKeys (O ,
symbol ))。
20.1.2.11.1 GetOwnPropertyKeys ( O ,
type )
抽象操作 GetOwnPropertyKeys 接受参数 O (一个 ECMAScript 语言值 )和
type (string 或 symbol ),返回一个包含
属性键 的 列表 的 正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 keys 为 ? obj .[[OwnPropertyKeys]] () 。
设 nameList 为一个新的空 列表 。
对于 keys 的每个元素 nextKey ,执行
如果 nextKey 是一个符号 且
type 是 symbol ,或者如果 nextKey
是一个字符串 且
type 是 string ,那么
将 nextKey 追加到 nameList 。
返回 nameList 。
20.1.2.12 Object.getPrototypeOf ( O )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
返回 ? obj .[[GetPrototypeOf]] () 。
20.1.2.13 Object.groupBy ( items , callback
)
注
callback 应该是一个接受两个参数的函数。groupBy 按升序为 items
中的每个元素调用一次 callback ,并构造一个新对象。callback 返回的每个值都被强制转换为 属性键 。对于每个这样的 属性键 ,结果对象有一个属性,其键是该 属性键 ,其值是一个数组,包含 callback
返回值强制转换为该键的所有元素。
callback 用两个参数调用:元素的值和元素的索引。
groupBy 的返回值是一个不继承自 %Object.prototype%
的对象。
此函数在被调用时执行以下步骤:
设 groups 为 ? GroupBy (items ,
callback , property )。
设 obj 为 OrdinaryObjectCreate (null )。
对于 groups 的每个 记录 { [[Key]] , [[Elements]] }
g ,执行
设 elements 为 CreateArrayFromList (g .[[Elements]] )。
执行 ! CreateDataPropertyOrThrow (obj ,
g .[[Key]] , elements )。
返回 obj 。
20.1.2.14 Object.hasOwn ( O , P )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 key 为 ? ToPropertyKey (P )。
返回 ? HasOwnProperty (obj ,
key )。
20.1.2.15 Object.is ( value1 , value2 )
此函数在被调用时执行以下步骤:
返回 SameValue (value1 ,
value2 )。
20.1.2.16 Object.isExtensible ( O )
此函数在被调用时执行以下步骤:
如果 O 不是一个对象 ,返回 false 。
返回 ? IsExtensible (O )。
20.1.2.17 Object.isFrozen ( O )
此函数在被调用时执行以下步骤:
如果 O 不是一个对象 ,返回 true 。
返回 ? TestIntegrityLevel (O ,
frozen )。
20.1.2.18 Object.isSealed ( O )
此函数在被调用时执行以下步骤:
如果 O 不是一个对象 ,返回 true 。
返回 ? TestIntegrityLevel (O ,
sealed )。
20.1.2.19 Object.keys ( O )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 keyList 为 ? EnumerableOwnProperties (obj ,
key )。
返回 CreateArrayFromList (keyList )。
20.1.2.20 Object.preventExtensions ( O )
此函数在被调用时执行以下步骤:
如果 O 不是一个对象 ,返回 O 。
设 status 为 ? O .[[PreventExtensions]] () 。
如果 status 是 false ,抛出 TypeError 异常。
返回 O 。
20.1.2.21 Object.prototype
Object.prototype 的初始值是 Object 原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.1.2.22 Object.seal ( O )
此函数在被调用时执行以下步骤:
如果 O 不是一个对象 ,返回 O 。
设 status 为 ? SetIntegrityLevel (O ,
sealed )。
如果 status 是 false ,抛出 TypeError 异常。
返回 O 。
20.1.2.23 Object.setPrototypeOf ( O , proto
)
此函数在被调用时执行以下步骤:
设 O 为 ? RequireObjectCoercible (O )。
如果 proto 不是一个对象 且 proto
不是 null ,抛出 TypeError 异常。
如果 O 不是一个对象 ,返回 O 。
设 status 为 ? O .[[SetPrototypeOf]] (proto )。
如果 status 是 false ,抛出 TypeError 异常。
返回 O 。
20.1.2.24 Object.values ( O )
此函数在被调用时执行以下步骤:
设 obj 为 ? ToObject (O )。
设 valueList 为 ? EnumerableOwnProperties (obj ,
value )。
返回 CreateArrayFromList (valueList )。
20.1.3 Object 原型对象的属性
Object 原型对象 :
是 %Object.prototype% 。
有一个 [[Extensible]] 内部槽,其值是 true 。
有为 普通对象 定义的内部方法,除了 [[SetPrototypeOf]] 方法,它按照 10.4.7.1
中的定义。
(因此,它是一个 不可变原型外来对象 。)
有一个 [[Prototype]] 内部槽,其值是 null 。
20.1.3.1 Object.prototype.constructor
Object.prototype.constructor 的初始值是 %Object% 。
20.1.3.2 Object.prototype.hasOwnProperty ( V )
此方法在被调用时执行以下步骤:
设 P 为 ? ToPropertyKey (V )。
设 O 为 ? ToObject (this 值)。
返回 ? HasOwnProperty (O ,
P )。
注
步骤 1 和 2 的顺序是为了确保,即使
this 值是 undefined 或
null ,在此规范的以前版本中步骤 1 会抛出的任何异常都将继续被抛出。
20.1.3.3 Object.prototype.isPrototypeOf ( V )
此方法在被调用时执行以下步骤:
如果 V 不是一个对象 ,返回 false 。
设 O 为 ? ToObject (this 值)。
重复,
设 V 为 ? V .[[GetPrototypeOf]] () 。
如果 V 是 null ,返回 false 。
如果 SameValue (O ,
V ) 是 true ,返回 true 。
注
步骤 1 和 2 的顺序保持了此规范的以前版本为
V 不是对象且 this 值是 undefined 或
null 的情况指定的行为。
20.1.3.4 Object.prototype.propertyIsEnumerable ( V )
此方法在被调用时执行以下步骤:
设 P 为 ? ToPropertyKey (V )。
设 O 为 ? ToObject (this 值)。
设 desc 为 ? O .[[GetOwnProperty]] (P )。
如果 desc 是 undefined ,返回 false 。
返回 desc .[[Enumerable]] 。
注 1
注 2
步骤 1 和 2 的顺序是为了确保,即使
this 值是 undefined 或
null ,在此规范的以前版本中步骤 1
会抛出的任何异常都将继续被抛出。
20.1.3.5 Object.prototype.toLocaleString ( [
reserved1 [ , reserved2 ] ] )
此方法在被调用时执行以下步骤:
设 O 为 this 值。
返回 ? Invoke (O ,
"toString" )。
此方法的可选参数未被使用,但旨在对应 ECMA-402 toLocaleString 方法使用的参数模式。不包含 ECMA-402
支持的实现不得将这些参数位置用于其他目的。
注 1
此方法为没有区域敏感的 toString 行为的对象提供通用的 toLocaleString
实现。Array、Number、Date 和 %TypedArray%
提供它们自己的区域敏感的 toLocaleString 方法。
注 2
ECMA-402 故意不为此默认实现提供替代方案。
20.1.3.6 Object.prototype.toString ( )
此方法在被调用时执行以下步骤:
如果 this 值是 undefined ,返回 "[object
Undefined]" 。
如果 this 值是 null ,返回 "[object
Null]" 。
设 O 为 ! ToObject (this 值)。
设 isArray 为 ? IsArray (O )。
如果 isArray 是 true ,设 builtinTag 为
"Array" 。
否则如果 O 有一个 [[ParameterMap]] 内部槽,设
builtinTag 为 "Arguments" 。
否则如果 O 有一个 [[Call]] 内部方法,设 builtinTag
为 "Function" 。
否则如果 O 有一个 [[ErrorData]] 内部槽,设
builtinTag 为 "Error" 。
否则如果 O 有一个 [[BooleanData]] 内部槽,设
builtinTag 为 "Boolean" 。
否则如果 O 有一个 [[NumberData]] 内部槽,设
builtinTag 为 "Number" 。
否则如果 O 有一个 [[StringData]] 内部槽,设
builtinTag 为 "String" 。
否则如果 O 有一个 [[DateValue]] 内部槽,设
builtinTag 为 "Date" 。
否则如果 O 有一个 [[RegExpMatcher]] 内部槽,设
builtinTag 为 "RegExp" 。
否则,设 builtinTag 为 "Object" 。
设 tag 为 ? Get (O ,
%Symbol.toStringTag% )。
如果 tag 不是一个字符串 ,设
tag 为 builtinTag 。
返回 "[object " 、tag 和 "]" 的 字符串连接 。
注
历史上,此方法偶尔被用来访问 [[Class]]
内部槽的字符串值,该内部槽在此规范的以前版本中用作各种内建对象的名义类型标签。上述 toString 的定义为使用
toString
作为那些特定类型的内建对象测试的遗留代码保持兼容性。它不为其他类型的内建或程序定义的对象提供可靠的类型测试机制。此外,程序可以以会使此类遗留类型测试的可靠性失效的方式使用
%Symbol.toStringTag% 。
20.1.3.7 Object.prototype.valueOf ( )
此方法在被调用时执行以下步骤:
返回 ? ToObject (this 值)。
20.1.3.8 Object.prototype.__proto__
Object.prototype.__proto__ 是一个 访问器属性 ,有特性 { [[Enumerable]] : false ,[[Configurable]] : true }。[[Get]] 和 [[Set]] 特性定义如下:
20.1.3.8.1 get Object.prototype.__proto__
[[Get]] 特性的值是一个不需要参数的内建函数。当被调用时执行以下步骤:
设 O 为 ? ToObject (this
值)。
返回 ? O .[[GetPrototypeOf]] () 。
20.1.3.8.2 set Object.prototype.__proto__
[[Set]] 特性的值是一个接受参数 proto 的内建函数。当被调用时执行以下步骤:
设 O 为 ? RequireObjectCoercible (this
值)。
如果 proto 不是一个对象 且 proto 不是
null ,返回 undefined 。
如果 O 不是一个对象 ,返回
undefined 。
设 status 为 ? O .[[SetPrototypeOf]] (proto )。
如果 status 是 false ,抛出 TypeError
异常。
返回 undefined 。
20.1.3.9 遗留的 Object.prototype 访问器方法
20.1.3.9.1 Object.prototype.__defineGetter__ ( P ,
getter )
此方法在被调用时执行以下步骤:
设 O 为 ? ToObject (this
值)。
如果 IsCallable (getter ) 是
false ,抛出 TypeError 异常。
设 desc 为 PropertyDescriptor { [[Get]] :
getter ,[[Enumerable]] :
true ,[[Configurable]] :
true }。
设 key 为 ? ToPropertyKey (P )。
执行 ? DefinePropertyOrThrow (O ,
key , desc )。
返回 undefined 。
20.1.3.9.2 Object.prototype.__defineSetter__ ( P ,
setter )
此方法在被调用时执行以下步骤:
设 O 为 ? ToObject (this
值)。
如果 IsCallable (setter ) 是
false ,抛出 TypeError 异常。
设 desc 为 PropertyDescriptor { [[Set]] :
setter ,[[Enumerable]] :
true ,[[Configurable]] :
true }。
设 key 为 ? ToPropertyKey (P )。
执行 ? DefinePropertyOrThrow (O ,
key , desc )。
返回 undefined 。
20.1.3.9.3 Object.prototype.__lookupGetter__ ( P
)
此方法在被调用时执行以下步骤:
设 O 为 ? ToObject (this
值)。
设 key 为 ? ToPropertyKey (P )。
重复,
设 desc 为 ? O .[[GetOwnProperty]] (key )。
如果 desc 不是 undefined ,那么
如果 IsAccessorDescriptor (desc )
是 true ,返回 desc .[[Get]] 。
返回 undefined 。
设 O 为 ? O .[[GetPrototypeOf]] () 。
如果 O 是 null ,返回
undefined 。
20.1.3.9.4 Object.prototype.__lookupSetter__ ( P
)
此方法在被调用时执行以下步骤:
设 O 为 ? ToObject (this
值)。
设 key 为 ? ToPropertyKey (P )。
重复,
设 desc 为 ? O .[[GetOwnProperty]] (key )。
如果 desc 不是 undefined ,那么
如果 IsAccessorDescriptor (desc )
是 true ,返回 desc .[[Set]] 。
返回 undefined 。
设 O 为 ? O .[[GetPrototypeOf]] () 。
如果 O 是 null ,返回
undefined 。
20.1.4 Object 实例的属性
Object 实例除了从 Object
原型对象 继承的属性外,没有特殊属性。
20.2 Function 对象
20.2.1 Function 构造器
Function 构造器 :
是 %Function% 。
是 全局对象 的 "Function" 属性的初始值。
当作为函数而不是作为 构造器 调用时,创建并初始化一个新的 函数对象 。因此函数调用 Function(…)
等价于使用相同参数的对象创建表达式 new Function(…)。
可以用作类定义中 extends 子句的值。打算继承指定的 Function 行为的子类 构造器 必须包含一个对 Function 构造器 的
super 调用,以创建和初始化具有内建函数行为所需的内部槽的子类实例。所有用于定义 函数对象 的 ECMAScript 语法形式都创建
Function 的实例。除了内建的 GeneratorFunction、AsyncFunction 和 AsyncGeneratorFunction 子类之外,没有语法方式来创建
Function 子类的实例。
20.2.1.1 Function ( ...parameterArgs ,
bodyArg )
最后一个参数(如果有的话)指定函数的主体(可执行代码);任何前面的参数指定形式参数。
此函数在被调用时执行以下步骤:
设 C 为 活动函数对象 。
如果 bodyArg 不存在,设 bodyArg 为空字符串。
返回 ? CreateDynamicFunction (C ,
NewTarget, normal , parameterArgs ,
bodyArg )。
注
为要指定的每个形式参数都有一个参数是允许的但不是必需的。例如,以下三个表达式都产生相同的结果:
new Function ("a" , "b" , "c" , "return a+b+c" )
new Function ("a, b, c" , "return a+b+c" )
new Function ("a,b" , "c" , "return a+b+c" )
20.2.1.1.1 CreateDynamicFunction ( constructor ,
newTarget , kind , parameterArgs , bodyArg )
抽象操作 CreateDynamicFunction 接受参数 constructor (一个 构造器 )、newTarget (一个
构造器 或
undefined )、kind (normal 、generator 、async
或 async-generator )、parameterArgs (ECMAScript 语言值 的 列表 )和
bodyArg (一个 ECMAScript 语言值 ),返回一个
包含 ECMAScript
函数对象 的 正常完成 或一个
抛出完成 。constructor
是执行此操作的 构造器 函数。newTarget 是最初应用
new 的 构造器 。parameterArgs 和
bodyArg 反映传递给 constructor 的参数值。当被调用时执行以下步骤:
如果 newTarget 是 undefined ,设 newTarget 为
constructor 。
如果 kind 是 normal ,那么
设 prefix 为 "function" 。
设 exprSym 为语法符号 FunctionExpression 。
设 bodySym 为语法符号 FunctionBody [~Yield,
~Await] 。
设 parameterSym 为语法符号 FormalParameters [~Yield,
~Await] 。
设 fallbackProto 为 "%Function.prototype%" 。
否则如果 kind 是 generator ,那么
设 prefix 为 "function*" 。
设 exprSym 为语法符号 GeneratorExpression 。
设 bodySym 为语法符号 GeneratorBody 。
设 parameterSym 为语法符号 FormalParameters [+Yield,
~Await] 。
设 fallbackProto 为
"%GeneratorFunction.prototype%" 。
否则如果 kind 是 async ,那么
设 prefix 为 "async function" 。
设 exprSym 为语法符号 AsyncFunctionExpression 。
设 bodySym 为语法符号 AsyncFunctionBody 。
设 parameterSym 为语法符号 FormalParameters [~Yield,
+Await] 。
设 fallbackProto 为
"%AsyncFunction.prototype%" 。
否则,
断言 :kind 是
async-generator 。
设 prefix 为 "async function*" 。
设 exprSym 为语法符号 AsyncGeneratorExpression 。
设 bodySym 为语法符号 AsyncGeneratorBody 。
设 parameterSym 为语法符号 FormalParameters [+Yield,
+Await] 。
设 fallbackProto 为
"%AsyncGeneratorFunction.prototype%" 。
设 argCount 为 parameterArgs 中元素的数量。
设 parameterStrings 为一个新的空 列表 。
对于 parameterArgs 的每个元素 arg ,执行
将 ? ToString (arg ) 追加到
parameterStrings 。
设 bodyString 为 ? ToString (bodyArg )。
设 currentRealm 为 当前 Realm 记录 。
执行 ? HostEnsureCanCompileStrings (currentRealm ,
parameterStrings , bodyString , false )。
设 P 为空字符串。
如果 argCount > 0,那么
设 P 为 parameterStrings [0]。
设 k 为 1。
重复,当 k < argCount 时,
设 nextArgString 为
parameterStrings [k ]。
设 P 为 P 、"," (逗号)和
nextArgString 的 字符串连接 。
设 k 为 k + 1。
设 bodyParseString 为 0x000A(换行符)、bodyString 和 0x000A(换行符)的
字符串连接 。
设 sourceString 为 prefix 、"
anonymous(" 、P 、0x000A(换行符)、")
{" 、bodyParseString 和 "}" 的 字符串连接 。
设 sourceText 为 StringToCodePoints (sourceString )。
设 parameters 为 ParseText (P ,
parameterSym )。
如果 parameters 是一个错误的 列表 ,抛出
SyntaxError 异常。
设 body 为 ParseText (bodyParseString ,
bodySym )。
如果 body 是一个错误的 列表 ,抛出
SyntaxError 异常。
注:参数和主体分别解析以确保各自都是有效的。例如,new Function("/*", "*/ ) {") 不会计算为函数。
注:如果达到这一步,sourceText 必须具有 exprSym
的语法(尽管反向含义不成立)。接下来两步的目的是执行直接应用于 exprSym 的任何早期错误规则。
设 expr 为 ParseText (sourceText ,
exprSym )。
如果 expr 是一个错误的 列表 ,抛出
SyntaxError 异常。
设 proto 为 ? GetPrototypeFromConstructor (newTarget ,
fallbackProto )。
设 env 为 currentRealm .[[GlobalEnv]] 。
设 privateEnv 为 null 。
设 F 为 OrdinaryFunctionCreate (proto ,
sourceText , parameters , body ,
non-lexical-this , env , privateEnv )。
执行 SetFunctionName (F ,
"anonymous" )。
如果 kind 是 generator ,那么
设 prototype 为 OrdinaryObjectCreate (%GeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] : prototype , [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] :
false })。
否则如果 kind 是 async-generator ,那么
设 prototype 为 OrdinaryObjectCreate (%AsyncGeneratorPrototype% )。
执行 ! DefinePropertyOrThrow (F ,
"prototype" , PropertyDescriptor { [[Value]] : prototype , [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] :
false })。
否则如果 kind 是 normal ,那么
执行 MakeConstructor (F )。
注:kind 为 async 的函数不可构造且没有 [[Construct]] 内部方法或 "prototype" 属性。
返回 F 。
注
CreateDynamicFunction 在它创建的任何 kind 不是 async
的函数上定义一个 "prototype" 属性,以提供函数将被用作 构造器 的可能性。
20.2.2 Function 构造器的属性
Function 构造器 :
20.2.2.1 Function.prototype
Function.prototype 的值是 Function
原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.2.3 Function 原型对象的属性
Function 原型对象 :
是 %Function.prototype% 。
本身是一个内建的 函数对象 。
接受任何参数并在调用时返回 undefined 。
没有 [[Construct]] 内部方法;它不能与 new 操作符一起用作 构造器 。
有一个 [[Prototype]] 内部槽,其值是 %Object.prototype% 。
没有 "prototype" 属性。
有一个 "length" 属性,其值是 +0 𝔽 。
有一个 "name" 属性,其值是空字符串。
注
Function 原型对象被指定为 函数对象 ,以确保与在 ECMAScript 2015 规范之前创建的
ECMAScript 代码的兼容性。
20.2.3.1 Function.prototype.apply ( thisArg ,
argArray )
此方法在被调用时执行以下步骤:
设 func 为 this 值。
如果 IsCallable (func ) 是
false ,抛出 TypeError 异常。
如果 argArray 是 undefined 或 null ,那么
执行 PrepareForTailCall ()。
返回 ? Call (func ,
thisArg )。
设 argList 为 ? CreateListFromArrayLike (argArray )。
执行 PrepareForTailCall ()。
返回 ? Call (func , thisArg ,
argList )。
注 1
thisArg 值被不加修改地传递作为 this
值。这是与第3版的变化,在第3版中,undefined 或 null 的
thisArg 被替换为 全局对象 ,并且 ToObject
被应用于所有其他值,该结果被传递作为 this 值。尽管 thisArg
被不加修改地传递,非严格函数 在进入函数时仍然执行这些转换。
注 2
如果 func 是箭头函数或 绑定函数外来对象 ,那么
thisArg 将在步骤 6 的函数
[[Call]] 中被忽略。
20.2.3.2 Function.prototype.bind ( thisArg ,
...args )
此方法在被调用时执行以下步骤:
设 Target 为 this 值。
如果 IsCallable (Target ) 是
false ,抛出 TypeError 异常。
设 F 为 ? BoundFunctionCreate (Target ,
thisArg , args )。
设 L 为 0。
设 targetHasLength 为 ? HasOwnProperty (Target ,
"length" )。
如果 targetHasLength 是 true ,那么
设 targetLen 为 ? Get (Target ,
"length" )。
如果 targetLen 是一个数值 ,那么
如果 targetLen 是 +∞ 𝔽 ,那么
设 L 为 +∞。
否则如果 targetLen 是 -∞ 𝔽 ,那么
设 L 为 0。
否则,
设 targetLenAsInt 为 ! ToIntegerOrInfinity (targetLen )。
断言 :targetLenAsInt
是 有限的 。
设 argCount 为 args 中元素的数量。
设 L 为 max (targetLenAsInt
- argCount , 0)。
执行 SetFunctionLength (F ,
L )。
设 targetName 为 ? Get (Target ,
"name" )。
如果 targetName 不是字符串 ,设
targetName 为空字符串。
执行 SetFunctionName (F ,
targetName , "bound" )。
返回 F 。
注 1
使用 Function.prototype.bind 创建的 函数对象 是 外来对象 。它们也没有
"prototype" 属性。
注 2
如果 Target 是箭头函数或 绑定函数外来对象 ,那么传递给此方法的
thisArg 将不会被后续对 F 的调用使用。
20.2.3.3 Function.prototype.call ( thisArg ,
...args )
此方法在被调用时执行以下步骤:
设 func 为 this 值。
如果 IsCallable (func ) 是
false ,抛出 TypeError 异常。
执行 PrepareForTailCall ()。
返回 ? Call (func ,
thisArg ,
args )。
注 1
thisArg 值被不加修改地传递作为 this
值。这是与第3版的变化,在第3版中,undefined 或 null 的
thisArg 被替换为 全局对象 ,并且 ToObject
被应用于所有其他值,该结果被传递作为 this 值。尽管 thisArg
被不加修改地传递,非严格函数 在进入函数时仍然执行这些转换。
注 2
如果 func 是箭头函数或 绑定函数外来对象 ,那么
thisArg 将在步骤 4 的函数 [[Call]] 中被忽略。
20.2.3.4 Function.prototype.constructor
Function.prototype.constructor 的初始值是 %Function% 。
20.2.3.5 Function.prototype.toString ( )
此方法在被调用时执行以下步骤:
设 func 为 this 值。
如果 func 是一个对象 ,func 有一个 [[SourceText]] 内部槽,func .[[SourceText]] 是一个 Unicode 码点序列,并且 HostHasSourceTextAvailable (func )
是 true ,那么
返回 CodePointsToString (func .[[SourceText]] )。
如果 func 是一个 内建函数对象 ,返回
func 的 实现定义的 字符串源代码表示。该表示必须具有 NativeFunction
的语法。另外,如果 func 有一个 [[InitialName]] 内部槽且
func .[[InitialName]] 是一个字符串 ,返回的字符串中与
NativeFunctionAccessor opt
PropertyName
匹配的部分必须是 func .[[InitialName]] 的值。
如果 func 是一个对象 且 IsCallable (func ) 是
true ,返回 func 的 实现定义的 字符串源代码表示。该表示必须具有 NativeFunction 的语法。
抛出 TypeError 异常。
NativeFunction :
function
NativeFunctionAccessor opt
PropertyName [~Yield,
~Await] opt
(
FormalParameters [~Yield,
~Await]
)
{
[
native
code
]
}
NativeFunctionAccessor
:
get
set
20.2.3.6 Function.prototype [ %Symbol.hasInstance% ] (
V )
此方法在被调用时执行以下步骤:
设 F 为 this 值。
返回 ? OrdinaryHasInstance (F ,
V )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
注
这是大多数函数继承的 %Symbol.hasInstance% 的默认实现。%Symbol.hasInstance%
被 instanceof 操作符调用,以确定值是否是特定 构造器 的实例。诸如
v instanceof F
的表达式计算为
F[%Symbol .hasInstance %](v)
构造器 函数可以通过在函数上公开不同的
%Symbol.hasInstance% 方法来控制哪些对象被 instanceof 识别为其实例。
此属性是不可写和不可配置的,以防止可能用于全局暴露绑定函数目标函数的篡改。
此方法的 "name" 属性的值是 "[Symbol.hasInstance]" 。
20.2.4 Function 实例
每个 Function 实例都是一个 ECMAScript 函数对象 ,并具有 表 30
中列出的内部槽。使用 Function.prototype.bind 方法(20.2.3.2 )创建的 函数对象 具有
表 31
中列出的内部槽。
Function 实例有以下属性:
20.2.4.1 length
"length" 属性的值是一个 整数 ,表示函数期望的典型参数数量。但是,语言允许使用其他数量的参数调用函数。当使用的参数数量与其
"length" 属性指定的数量不同时,函数的行为取决于该函数。此属性有特性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true }。
20.2.4.2 name
"name" 属性的值 是一个字符串 ,用于描述该函数。该名称没有语义意义,但通常是在
ECMAScript
源文本 中的定义点用来引用函数的变量或 属性名 。此属性有特性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true }。
本规范没有关联上下文名称的匿名函数对象使用空字符串作为 "name" 属性的值。
20.2.4.3 prototype
可以用作 构造器 的
Function 实例有一个 "prototype" 属性。每当创建这样的 Function 实例时,还会创建另一个 普通对象 ,并且它是函数的 "prototype"
属性的初始值。除非另有说明,"prototype" 属性的值用于初始化当该函数作为 构造器 调用时所创建对象的 [[Prototype]] 内部槽。
此属性有特性 { [[Writable]] :
true , [[Enumerable]] : false ,
[[Configurable]] : false }。
注
使用 Function.prototype.bind 创建的 函数对象 ,或通过求值 MethodDefinition (不是 GeneratorMethod 或
AsyncGeneratorMethod )或
ArrowFunction
创建的函数对象没有 "prototype" 属性。
20.2.5 HostHasSourceTextAvailable ( func )
宿主定义的 抽象操作
HostHasSourceTextAvailable 接受参数 func (一个 函数对象 )并返回一个布尔值。它允许 宿主环境 阻止为
func 提供源文本。
HostHasSourceTextAvailable 的实现必须符合以下要求:
它必须相对于其参数是确定性的。每次使用特定的 func 作为参数调用时,它必须返回相同的结果。
HostHasSourceTextAvailable 的默认实现是返回 true 。
20.3 Boolean 对象
20.3.1 Boolean 构造器
Boolean 构造器 :
是 %Boolean% 。
是 全局对象 的 "Boolean" 属性的初始值。
当作为 构造器 调用时,创建并初始化一个新的 Boolean 对象。
当作为函数而不是作为 构造器 调用时,执行类型转换。
可以用作类定义中 extends 子句的值。打算继承指定的 Boolean 行为的子类 构造器 必须包含一个对 Boolean 构造器 的
super 调用,以创建和初始化具有 [[BooleanData]] 内部槽的子类实例。
20.3.1.1 Boolean ( value )
此函数在被调用时执行以下步骤:
设 b 为 ToBoolean (value )。
如果 NewTarget 是 undefined ,返回 b 。
设 O 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%Boolean.prototype%" , « [[BooleanData]] »)。
设 O .[[BooleanData]] 为 b 。
返回 O 。
20.3.2 Boolean 构造器的属性
Boolean 构造器 :
20.3.2.1 Boolean.prototype
Boolean.prototype 的初始值是 Boolean 原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.3.3 Boolean 原型对象的属性
Boolean 原型对象 :
是 %Boolean.prototype% 。
是一个 普通对象 。
本身是一个 Boolean 对象;它有一个 [[BooleanData]] 内部槽,值为
false 。
有一个 [[Prototype]] 内部槽,其值是 %Object.prototype% 。
20.3.3.1 Boolean.prototype.constructor
Boolean.prototype.constructor 的初始值是 %Boolean% 。
20.3.3.2 Boolean.prototype.toString ( )
此方法在被调用时执行以下步骤:
设 b 为 ? ThisBooleanValue (this
value)。
如果 b 是 true ,返回 "true" ;否则返回
"false" 。
20.3.3.3 Boolean.prototype.valueOf ( )
此方法在被调用时执行以下步骤:
返回 ? ThisBooleanValue (this
value)。
20.3.3.3.1 ThisBooleanValue ( value )
抽象操作 ThisBooleanValue 接受参数 value (一个 ECMAScript 语言值 )并返回一个
包含 布尔值的 正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
如果 value 是一个布尔值 ,返回
value 。
如果 value 是一个对象 且 value 有一个 [[BooleanData]] 内部槽,那么
设 b 为 value .[[BooleanData]] 。
断言 :b 是一个布尔值 。
返回 b 。
抛出 TypeError 异常。
20.3.4 Boolean 实例的属性
Boolean 实例是从 Boolean 原型对象 继承属性的
普通对象 。Boolean 实例有一个 [[BooleanData]] 内部槽。[[BooleanData]] 内部槽是此
Boolean 对象表示的布尔值。
20.4 Symbol 对象
20.4.1 Symbol 构造器
Symbol 构造器 :
是 %Symbol% 。
是 全局对象 的 "Symbol" 属性的初始值。
当作为函数调用时返回一个新的 Symbol 值。
不打算与 new 操作符一起使用。
不打算被子类化。
可以用作类定义中 extends 子句的值,但对它的 super 调用将导致异常。
20.4.1.1 Symbol ( [ description ] )
此函数在被调用时执行以下步骤:
如果 NewTarget 不是 undefined ,抛出 TypeError 异常。
如果 description 是 undefined ,设 descString
为 undefined 。
否则,设 descString 为 ? ToString (description )。
返回一个新的 Symbol,其 [[Description]] 是 descString 。
20.4.2 Symbol 构造器的属性
Symbol 构造器 :
20.4.2.1 Symbol.asyncIterator
Symbol.asyncIterator 的初始值是众所周知的符号 %Symbol.asyncIterator% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.2 Symbol.for ( key )
此函数在被调用时执行以下步骤:
设 stringKey 为 ? ToString (key )。
对于 GlobalSymbolRegistry 列表 的每个元素
e ,执行
如果 e .[[Key]] 是 stringKey ,
返回 e .[[Symbol]] 。
断言 :GlobalSymbolRegistry
列表 当前不包含 stringKey 的条目。
设 newSymbol 为一个新的 Symbol,其 [[Description]] 是
stringKey 。
将 GlobalSymbolRegistry 记录 { [[Key]] : stringKey , [[Symbol]] : newSymbol } 追加到 GlobalSymbolRegistry 列表 。
返回 newSymbol 。
GlobalSymbolRegistry 列表 是一个只能追加的 列表 ,全局可用。它被所有 Realm 共享。在任何 ECMAScript
代码的求值之前,它被初始化为一个新的空 列表 。GlobalSymbolRegistry
列表的元素是具有 表 63 中定义的结构的
记录 。
表 63:GlobalSymbolRegistry 记录 字段
字段名
值
用法
[[Key]]
一个字符串
用于全局标识 Symbol 的字符串键。
[[Symbol]]
一个 Symbol
可以从任何 Realm 检索的符号。
20.4.2.3 Symbol.hasInstance
Symbol.hasInstance 的初始值是众所周知的符号 %Symbol.hasInstance% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.4 Symbol.isConcatSpreadable
Symbol.isConcatSpreadable 的初始值是众所周知的符号 %Symbol.isConcatSpreadable% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.5 Symbol.iterator
Symbol.iterator 的初始值是众所周知的符号 %Symbol.iterator% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.6 Symbol.keyFor ( sym )
此函数在被调用时执行以下步骤:
如果 sym 不是
Symbol ,抛出 TypeError 异常。
返回 KeyForSymbol (sym )。
20.4.2.7 Symbol.match
Symbol.match 的初始值是众所周知的符号 %Symbol.match% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.8 Symbol.matchAll
Symbol.matchAll 的初始值是众所周知的符号 %Symbol.matchAll% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.9 Symbol.prototype
Symbol.prototype 的初始值是 Symbol 原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.10 Symbol.replace
Symbol.replace 的初始值是众所周知的符号 %Symbol.replace% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.11 Symbol.search
Symbol.search 的初始值是众所周知的符号 %Symbol.search% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.12 Symbol.species
Symbol.species 的初始值是众所周知的符号 %Symbol.species% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.13 Symbol.split
Symbol.split 的初始值是众所周知的符号 %Symbol.split% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.14 Symbol.toPrimitive
Symbol.toPrimitive 的初始值是众所周知的符号 %Symbol.toPrimitive% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.15 Symbol.toStringTag
Symbol.toStringTag 的初始值是众所周知的符号 %Symbol.toStringTag% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.2.16 Symbol.unscopables
Symbol.unscopables 的初始值是众所周知的符号 %Symbol.unscopables% (表
1 )。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.4.3 Symbol 原型对象的属性
Symbol 原型对象 :
20.4.3.1 Symbol.prototype.constructor
Symbol.prototype.constructor 的初始值是 %Symbol% 。
20.4.3.2 get Symbol.prototype.description
Symbol.prototype.description 是一个 访问器属性 ,其 set 访问器函数是
undefined 。其 get 访问器函数在被调用时执行以下步骤:
设 s 为 this 值。
设 sym 为 ? ThisSymbolValue (s )。
返回 sym .[[Description]] 。
20.4.3.3 Symbol.prototype.toString ( )
此方法在被调用时执行以下步骤:
设 sym 为 ? ThisSymbolValue (this
value)。
返回 SymbolDescriptiveString (sym )。
20.4.3.3.1 SymbolDescriptiveString ( sym )
抽象操作 SymbolDescriptiveString 接受参数 sym (一个 Symbol)并返回一个字符串。当被调用时执行以下步骤:
设 desc 为 sym 的 [[Description]] 值。
如果 desc 是 undefined ,设 desc 为空字符串。
断言 :desc 是一个字符串 。
返回 "Symbol(" 、desc 和 ")" 的
字符串连接 。
20.4.3.4 Symbol.prototype.valueOf ( )
此方法在被调用时执行以下步骤:
返回 ? ThisSymbolValue (this
value)。
20.4.3.4.1 ThisSymbolValue ( value )
抽象操作 ThisSymbolValue 接受参数 value (一个 ECMAScript 语言值 )并返回一个
包含 Symbol 的
正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
如果 value 是一个
Symbol ,返回 value 。
如果 value 是一个对象 且 value 有一个 [[SymbolData]] 内部槽,那么
设 s 为 value .[[SymbolData]] 。
断言 :s 是一个
Symbol 。
返回 s 。
抛出 TypeError 异常。
20.4.3.5 Symbol.prototype [ %Symbol.toPrimitive% ] (
hint )
此方法被 ECMAScript 语言操作符调用,以将 Symbol 对象转换为原始值。
当被调用时执行以下步骤:
返回 ? ThisSymbolValue (this
value)。
注
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
此方法的 "name" 属性的值是 "[Symbol.toPrimitive]" 。
20.4.3.6 Symbol.prototype [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值是字符串值
"Symbol" 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
20.4.4 Symbol 实例的属性
Symbol 实例是从 Symbol 原型对象 继承属性的
普通对象 。Symbol 实例有一个 [[SymbolData]] 内部槽。[[SymbolData]] 内部槽是此 Symbol
对象表示的 Symbol 值。
20.4.5 Symbol 的抽象操作
20.4.5.1 KeyForSymbol ( sym )
抽象操作 KeyForSymbol 接受参数 sym (一个 Symbol)并返回一个字符串或 undefined 。如果
sym 在 GlobalSymbolRegistry 列表 中,将返回用于注册
sym 的字符串。当被调用时执行以下步骤:
对于 GlobalSymbolRegistry 列表 的每个元素
e ,执行
如果 SameValue (e .[[Symbol]] , sym ) 是
true ,返回 e .[[Key]] 。
断言 :GlobalSymbolRegistry
列表 当前不包含 sym 的条目。
返回 undefined 。
20.5 Error 对象
当运行时错误发生时,Error 对象的实例作为异常被抛出。Error 对象也可以作为用户定义异常类的基对象。
当 ECMAScript 实现检测到运行时错误时,它会抛出在 20.5.5 中定义的
NativeError 对象之一的新实例,或在 20.5.7 中定义的 AggregateError 对象的新实例。
20.5.1 Error 构造器
Error 构造器 :
是 %Error% 。
是 全局对象 的 "Error" 属性的初始值。
当作为函数而不是作为 构造器 调用时,创建并初始化一个新的 Error 对象。因此函数调用
Error(…) 等同于具有相同参数的对象创建表达式 new Error(…)。
可以用作类定义中 extends 子句的值。打算继承指定的 Error 行为的子类 构造器 必须包含一个对 Error 构造器 的
super 调用,以创建和初始化具有 [[ErrorData]] 内部槽的子类实例。
20.5.1.1 Error ( message [ , options ] )
此函数在被调用时执行以下步骤:
如果 NewTarget 是 undefined ,设 newTarget 为 活动函数对象 ;否则设
newTarget 为 NewTarget。
设 O 为 ? OrdinaryCreateFromConstructor (newTarget ,
"%Error.prototype%" , « [[ErrorData]] »)。
如果 message 不是 undefined ,那么
设 msg 为 ? ToString (message )。
执行 CreateNonEnumerableDataPropertyOrThrow (O ,
"message" , msg )。
执行 ? InstallErrorCause (O ,
options )。
返回 O 。
20.5.2 Error 构造器的属性
Error 构造器 :
20.5.2.1 Error.prototype
Error.prototype 的初始值是 Error 原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
20.5.3 Error 原型对象的属性
Error 原型对象 :
是 %Error.prototype% 。
是一个 普通对象 。
不是 Error 实例,并且没有 [[ErrorData]] 内部槽。
有一个 [[Prototype]] 内部槽,其值是 %Object.prototype% 。
20.5.3.1 Error.prototype.constructor
Error.prototype.constructor 的初始值是 %Error% 。
20.5.3.2 Error.prototype.message
Error.prototype.message 的初始值是空字符串。
20.5.3.3 Error.prototype.name
Error.prototype.name 的初始值是 "Error" 。
20.5.3.4 Error.prototype.toString ( )
此方法在被调用时执行以下步骤:
设 O 为 this 值。
如果 O 不是对象 ,抛出 TypeError
异常。
设 name 为 ? Get (O ,
"name" )。
如果 name 是 undefined ,设 name 为
"Error" ;否则设 name 为 ? ToString (name )。
设 msg 为 ? Get (O ,
"message" )。
如果 msg 是 undefined ,设 msg 为空字符串;否则设
msg 为 ? ToString (msg )。
如果 name 是空字符串,返回 msg 。
如果 msg 是空字符串,返回 name 。
返回 name 、代码单元 0x003A(冒号)、代码单元 0x0020(空格)和 msg 的 字符串连接 。
20.5.4 Error 实例的属性
Error 实例是从 Error 原型对象 继承属性的
普通对象 ,并有一个值为 undefined 的 [[ErrorData]] 内部槽。[[ErrorData]] 的唯一指定用途是在
Object.prototype.toString 中将 Error、AggregateError 和 NativeError 实例标识为
Error 对象。
20.5.5 本标准中使用的原生 Error 类型
当检测到运行时错误时,会抛出下面 NativeError 对象之一或 AggregateError 对象的新实例。所有 NativeError
对象共享相同的结构,如 20.5.6 中所述。
20.5.5.1 EvalError
EvalError 构造器 是 %EvalError% 。
此异常当前在本规范中未使用。保留此对象是为了与本规范的先前版本兼容。
20.5.5.2 RangeError
RangeError 构造器 是 %RangeError% 。
表示一个不在允许值集合或范围内的值。
20.5.5.3 ReferenceError
ReferenceError 构造器 是 %ReferenceError% 。
表示检测到无效引用。
20.5.5.4 SyntaxError
SyntaxError 构造器 是 %SyntaxError% 。
表示发生了解析错误。
20.5.5.5 TypeError
TypeError 构造器 是 %TypeError% 。
TypeError 用于表示不成功的操作,当其他 NativeError 对象都不适合表示失败原因时使用。
20.5.5.6 URIError
URIError 构造器 是 %URIError% 。
表示某个全局 URI 处理函数的使用方式与其定义不兼容。
20.5.6 NativeError 对象结构
这些对象中的每一个都具有下面描述的结构,仅在用作 构造器 名称和原型对象的 "name" 属性中使用的名称上有所不同。
对于每个错误对象,定义中对 NativeError 的引用应替换为 20.5.5 中的相应错误对象名称。
20.5.6.1 NativeError 构造器
每个 NativeError 构造器 :
当作为函数而不是作为 构造器 调用时,创建并初始化一个新的 NativeError
对象。将对象作为函数调用等同于使用相同参数将其作为 构造器 调用。因此函数调用
NativeError (…) 等同于具有相同参数的对象创建表达式
new NativeError (…)。
可以用作类定义中 extends 子句的值。打算继承指定的 NativeError 行为的子类 构造器 必须包含一个对
NativeError 构造器 的 super 调用,以创建和初始化具有 [[ErrorData]] 内部槽的子类实例。
20.5.6.1.1 NativeError ( message [ ,
options ] )
每个 NativeError 函数在被调用时执行以下步骤:
如果 NewTarget 是 undefined ,设 newTarget 为 活动函数对象 ;否则设
newTarget 为 NewTarget。
设 O 为
? OrdinaryCreateFromConstructor (newTarget ,
"%NativeError .prototype%", « [[ErrorData]] »)。
如果 message 不是 undefined ,那么
设 msg 为 ? ToString (message )。
执行 CreateNonEnumerableDataPropertyOrThrow (O ,
"message" , msg )。
执行 ? InstallErrorCause (O ,
options )。
返回 O 。
在步骤 2
中传递的字符串的实际值是
"%EvalError.prototype%" 、"%RangeError.prototype%" 、"%ReferenceError.prototype%" 、"%SyntaxError.prototype%" 、"%TypeError.prototype%"
或 "%URIError.prototype%" 中的一个,对应于正在定义的 NativeError
构造器 。
20.5.6.2 NativeError 构造器的属性
每个 NativeError 构造器 :
有一个 [[Prototype]] 内部槽,其值是 %Error% 。
有一个 "name" 属性,其值是字符串值 "NativeError " 。
有以下属性:
20.5.6.2.1 NativeError .prototype
NativeError .prototype 的初始值是一个 NativeError
原型对象(20.5.6.3 )。每个
NativeError 构造器 都有一个不同的原型对象。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
false }。
20.5.6.3 NativeError 原型对象的属性
每个 NativeError 原型对象 :
20.5.6.3.1 NativeError .prototype.constructor
给定 NativeError 构造器 的原型的 "constructor"
属性的初始值是 构造器 本身。
20.5.6.3.2 NativeError .prototype.message
给定 NativeError 构造器 的原型的 "message"
属性的初始值是空字符串。
20.5.6.3.3 NativeError .prototype.name
给定 NativeError 构造器 的原型的 "name" 属性的初始值是由
构造器 名称(代替 NativeError
使用的名称)组成的字符串值。
20.5.6.4 NativeError 实例的属性
NativeError 实例是从其 NativeError 原型对象继承属性的 普通对象 ,并有一个值为 undefined 的
[[ErrorData]] 内部槽。[[ErrorData]] 的唯一指定用途是被
Object.prototype.toString(20.1.3.6 )用来标识
Error、AggregateError 或 NativeError 实例。
20.5.7 AggregateError 对象
20.5.7.1 AggregateError 构造器
AggregateError 构造器 :
是 %AggregateError% 。
是 全局对象 的
"AggregateError" 属性的初始值。
当作为函数而不是作为 构造器 调用时,创建并初始化一个新的 AggregateError 对象。因此函数调用
AggregateError(…) 等同于具有相同参数的对象创建表达式 new AggregateError(…)。
可以用作类定义中 extends 子句的值。打算继承指定的 AggregateError 行为的子类 构造器 必须包含一个对
AggregateError 构造器 的 super 调用,以创建和初始化具有 [[ErrorData]] 内部槽的子类实例。
20.5.7.1.1 AggregateError ( errors ,
message [ , options ] )
此函数在被调用时执行以下步骤:
如果 NewTarget 是 undefined ,设 newTarget 为 活动函数对象 ;否则设
newTarget 为 NewTarget。
设 O 为 ? OrdinaryCreateFromConstructor (newTarget ,
"%AggregateError.prototype%" , « [[ErrorData]] »)。
如果 message 不是 undefined ,那么
设 msg 为 ? ToString (message )。
执行 CreateNonEnumerableDataPropertyOrThrow (O ,
"message" , msg )。
执行 ? InstallErrorCause (O ,
options )。
设 errorsList 为 ? IteratorToList (? GetIterator (errors ,
sync ))。
执行 ! DefinePropertyOrThrow (O ,
"errors" , PropertyDescriptor { [[Configurable]] : true , [[Enumerable]] : false , [[Writable]] : true , [[Value]] : CreateArrayFromList (errorsList ) })。
返回 O 。
20.5.7.2 AggregateError 构造器的属性
AggregateError 构造器 :
有一个 [[Prototype]] 内部槽,其值是 %Error% 。
有以下属性:
20.5.7.2.1 AggregateError.prototype
AggregateError.prototype 的初始值是 %AggregateError.prototype% 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
false }。
20.5.7.3 AggregateError 原型对象的属性
AggregateError 原型对象 :
是 %AggregateError.prototype% 。
是一个 普通对象 。
不是 Error 实例或 AggregateError 实例,并且没有 [[ErrorData]] 内部槽。
有一个 [[Prototype]] 内部槽,其值是 %Error.prototype% 。
20.5.7.3.1 AggregateError.prototype.constructor
AggregateError.prototype.constructor 的初始值是 %AggregateError% 。
20.5.7.3.2 AggregateError.prototype.message
AggregateError.prototype.message 的初始值是空字符串。
20.5.7.3.3 AggregateError.prototype.name
AggregateError.prototype.name 的初始值是 "AggregateError" 。
20.5.7.4 AggregateError 实例的属性
AggregateError 实例是从其 AggregateError
原型对象 继承属性的 普通对象 ,并有一个值为 undefined 的
[[ErrorData]] 内部槽。[[ErrorData]] 的唯一指定用途是被
Object.prototype.toString(20.1.3.6 )用来标识
Error、AggregateError 或 NativeError 实例。
20.5.8 Error 对象的抽象操作
20.5.8.1 InstallErrorCause ( O , options )
抽象操作 InstallErrorCause 接受参数 O (一个对象)和 options (一个 ECMAScript 语言值 ),并返回一个 包含
unused 的 正常完成 或一个 抛出完成 。当
options 上存在 "cause" 属性时,它用于在 O 上创建一个
"cause" 属性。当被调用时执行以下步骤:
如果 options 是一个对象 且 ? HasProperty (options ,
"cause" ) 是 true ,那么
设 cause 为 ? Get (options ,
"cause" )。
执行 CreateNonEnumerableDataPropertyOrThrow (O ,
"cause" , cause )。
返回 unused 。
21 数字和日期
21.1 Number 对象
21.1.1 Number 构造器
Number 构造器 :
是 %Number% 。
是 全局对象 的 "Number" 属性的初始值。
当作为 构造器 调用时,创建并初始化一个新的 Number 对象。
当作为函数而不是作为 构造器 调用时,执行类型转换。
可以用作类定义中 extends 子句的值。打算继承指定的 Number 行为的子类 构造器 必须包含一个对 Number 构造器 的
super 调用,以创建和初始化具有 [[NumberData]] 内部槽的子类实例。
21.1.1.1 Number ( value )
此函数在被调用时执行以下步骤:
如果 value 存在,那么
设 prim 为 ? ToNumeric (value )。
如果 prim 是
BigInt ,设 n 为 𝔽 (ℝ (prim ))。
否则,设 n 为 prim 。
否则,
设 n 为 +0 𝔽 。
如果 NewTarget 是 undefined ,返回 n 。
设 O 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%Number.prototype%" , « [[NumberData]] »)。
设置 O .[[NumberData]] 为 n 。
返回 O 。
21.1.2 Number 构造器的属性
Number 构造器 :
21.1.2.1 Number.EPSILON
Number.EPSILON 的值是 1 与大于 1 的可表示为 Number 值的最小值之间差值的幅度的 Number
值 ,约为 2.2204460492503130808472633361816 × 10-16 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.2 Number.isFinite ( number )
此函数在被调用时执行以下步骤:
如果 number 不是
Number ,返回 false 。
如果 number 不是 有限的 ,返回 false 。
否则,返回 true 。
21.1.2.3 Number.isInteger ( number )
此函数在被调用时执行以下步骤:
如果 number 是 整数 Number ,返回 true 。
返回 false 。
21.1.2.4 Number.isNaN ( number )
此函数在被调用时执行以下步骤:
如果 number 不是
Number ,返回 false 。
如果 number 是 NaN ,返回 true 。
否则,返回 false 。
注
此函数与全局 isNaN 函数(19.2.3 )的不同之处在于,它在确定参数是否为
NaN 之前不会将其转换为 Number。
21.1.2.5 Number.isSafeInteger ( number )
注
当且仅当 n 的 Number 值 不是任何其他 整数 的 Number
值 时,整数 n 是"安全整数 "。
此函数在被调用时执行以下步骤:
如果 number 是 整数 Number ,那么
如果 abs (ℝ (number )) ≤
253 - 1,返回 true 。
返回 false 。
21.1.2.6 Number.MAX_SAFE_INTEGER
注
由于 IEEE
754-2019 精度限制所必需的舍入行为,每个大于
Number.MAX_SAFE_INTEGER 的 整数 的 Number 值 都与至少一个其他
整数 共享。因此,这些大幅度的 整数 不是 安全的 ,并且不保证能准确表示为 Number
值,甚至不保证彼此可区分。例如,9007199254740992 和 9007199254740993 都计算为
Number 值 9007199254740992 𝔽 。
Number.MAX_SAFE_INTEGER 的值是
9007199254740991 𝔽 (𝔽 (253 - 1))。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.7 Number.MAX_VALUE
Number.MAX_VALUE 的值是 Number
类型 的最大正 有限 值,约为 1.7976931348623157 ×
10308 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.8 Number.MIN_SAFE_INTEGER
注
由于 IEEE
754-2019 精度限制所必需的舍入行为,每个小于
Number.MIN_SAFE_INTEGER 的 整数 的 Number 值 都与至少一个其他
整数 共享。因此,这些大幅度的 整数 不是 安全的 ,并且不保证能准确表示为 Number
值,甚至不保证彼此可区分。例如,-9007199254740992 和 -9007199254740993 都计算为
Number 值 -9007199254740992 𝔽 。
Number.MIN_SAFE_INTEGER 的值是
-9007199254740991 𝔽 (𝔽 (-(253 - 1)))。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.9 Number.MIN_VALUE
Number.MIN_VALUE 的值是 Number
类型 的最小正值,约为 5 × 10-324 。
在 IEEE
754-2019
双精度二进制表示中,最小可能值是非正规化数。如果实现不支持非正规化值,Number.MIN_VALUE 的值必须是实现实际能表示的最小非零正值。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.10 Number.NaN
Number.NaN 的值是 NaN 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.11 Number.NEGATIVE_INFINITY
Number.NEGATIVE_INFINITY 的值是 -∞ 𝔽 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.12 Number.parseFloat ( string )
"parseFloat" 属性的初始值是 %parseFloat% 。
21.1.2.13 Number.parseInt ( string , radix
)
"parseInt" 属性的初始值是 %parseInt% 。
21.1.2.14 Number.POSITIVE_INFINITY
Number.POSITIVE_INFINITY 的值是 +∞ 𝔽 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.2.15 Number.prototype
Number.prototype 的初始值是 Number 原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.1.3 Number 原型对象的属性
Number 原型对象 :
是 %Number.prototype% 。
是一个 普通对象 。
本身是一个 Number 对象;它有一个 [[NumberData]] 内部槽,值为
+0 𝔽 。
有一个 [[Prototype]] 内部槽,其值是 %Object.prototype% 。
除非明确说明,下面定义的 Number 原型对象的方法不是通用的,传递给它们的 this 值必须是 Number 值或具有已初始化为 Number 值的
[[NumberData]] 内部槽的对象。
方法规范中的短语"此 Number 值"是指通过将方法调用的 this 值作为参数调用抽象操作 ThisNumberValue 返回的结果。
21.1.3.1 Number.prototype.constructor
Number.prototype.constructor 的初始值是 %Number% 。
21.1.3.2 Number.prototype.toExponential (
fractionDigits )
此方法返回一个字符串,包含以十进制指数记法表示的此 Number 值,有效数字的小数点前有一位数字,小数点后有 fractionDigits 位数字。如果
fractionDigits 是 undefined ,它包含尽可能多的有效数字位数以唯一地指定 Number(就像在
ToString
中一样,除了在这种情况下 Number 总是以指数记法输出)。
当被调用时执行以下步骤:
设 x 为 ? ThisNumberValue (this
value)。
设 f 为 ? ToIntegerOrInfinity (fractionDigits )。
断言 :如果
fractionDigits 是 undefined ,那么 f 是 0。
如果 x 不是 有限的 ,返回 Number::toString (x ,
10)。
如果 f < 0 或 f > 100,抛出 RangeError 异常。
设置 x 为 ℝ (x )。
设 s 为空字符串。
如果 x < 0,那么
设置 s 为 "-" 。
设置 x 为 -x 。
如果 x = 0,那么
设 m 为由 f + 1 个代码单元 0x0030(数字零)组成的字符串值。
设 e 为 0。
否则,
如果 fractionDigits 不是 undefined ,那么
设 e 和 n 为 整数 ,使得
10f ≤ n <
10f + 1 且 n ×
10e - f - x
尽可能接近零。如果有两组这样的 e 和 n ,选择使 n ×
10e - f 更大的 e 和
n 。
否则,
设
e 、n 和 ff 为 整数 ,使得 ff ≥
0,10ff ≤ n <
10ff + 1 ,𝔽 (n ×
10e - ff ) 是 𝔽 (x ),
且 ff 尽可能小。注意 n 的十进制表示有 ff + 1
位数字,n 不能被 10 整除,且 n 的最低有效位不一定由这些条件唯一确定。
设置 f 为 ff 。
设 m 为由 n 的十进制表示的数字组成的字符串值(按顺序,没有前导零)。
如果 f ≠ 0,那么
设 a 为 m 的第一个代码单元。
设 b 为 m 的其他 f 个代码单元。
设置 m 为 a 、"." 和 b 的
字符串连接 。
如果 e = 0,那么
设 c 为 "+" 。
设 d 为 "0" 。
否则,
如果 e > 0,那么
设 c 为 "+" 。
否则,
断言 :e < 0。
设 c 为 "-" 。
设置 e 为 -e 。
设 d 为由 e 的十进制表示的数字组成的字符串值(按顺序,没有前导零)。
设置 m 为 m 、"e" 、c 和 d 的
字符串连接 。
返回 s 和 m 的 字符串连接 。
注
对于提供比上述规则要求更准确转换的实现,建议将以下步骤 10.b.i
的替代版本用作指导:
设 e 、n 和 f 为 整数 ,使得 f ≥ 0,
10f ≤ n < 10f + 1 ,
𝔽 (n × 10e -
f ) 是 𝔽 (x ),且 f 尽可能小。如果
n 有多种可能性,选择使 𝔽 (n ×
10e - f ) 在值上最接近 𝔽 (x ) 的
n 值。如果有两个这样的可能 n 值,选择偶数的那个。
21.1.3.3 Number.prototype.toFixed ( fractionDigits )
注 1
此方法返回一个字符串,包含以十进制定点记法表示的此 Number 值,小数点后有 fractionDigits 位数字。如果
fractionDigits 是 undefined ,假定为 0。
当被调用时执行以下步骤:
设 x 为 ? ThisNumberValue (this
value)。
设 f 为 ? ToIntegerOrInfinity (fractionDigits )。
断言 :如果
fractionDigits 是 undefined ,那么 f 是 0。
如果 f 不是 有限的 ,抛出 RangeError 异常。
如果 f < 0 或 f > 100,抛出 RangeError 异常。
如果 x 不是 有限的 ,返回 Number::toString (x ,
10)。
设置 x 为 ℝ (x )。
设 s 为空字符串。
如果 x < 0,那么
设置 s 为 "-" 。
设置 x 为 -x 。
如果 x ≥ 1021 ,那么
设 m 为 ! ToString (𝔽 (x ))。
否则,
设 n 为一个 整数 ,使得 n /
10f - x 尽可能接近零。如果有两个这样的 n ,选择较大的
n 。
如果 n = 0,设 m 为 "0" 。否则,设
m 为由 n 的十进制表示的数字组成的字符串值(按顺序,没有前导零)。
如果 f ≠ 0,那么
设 k 为 m 的长度。
如果 k ≤ f ,那么
设 z 为由 f + 1 - k 个代码单元
0x0030(数字零)组成的字符串值。
设置 m 为 z 和 m 的 字符串连接 。
设置 k 为 f + 1。
设 a 为 m 的前 k - f 个代码单元。
设 b 为 m 的其他 f 个代码单元。
设置 m 为 a 、"." 和 b
的 字符串连接 。
返回 s 和 m 的 字符串连接 。
注 2
对于某些值,toFixed 的输出可能比 toString 更精确,因为 toString
只打印足够的有效数字来区分该数字与相邻的 Number 值。例如,
(1000000000000000128).toString() 返回
"1000000000000000100" ,而
(1000000000000000128).toFixed(0) 返回
"1000000000000000128" 。
21.1.3.4 Number.prototype.toLocaleString ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范中的规定实现此方法。如果 ECMAScript 实现不包含 ECMA-402
API,则使用此方法的以下规范:
此方法产生一个字符串值,该值表示根据 宿主环境 当前区域设置的约定格式化的此 Number 值。此方法是 实现定义的 ,允许(但不鼓励)它返回与
toString 相同的内容。
此方法的可选参数的含义在 ECMA-402 规范中定义;不包含 ECMA-402 支持的实现不得将这些参数位置用于任何其他用途。
21.1.3.5 Number.prototype.toPrecision ( precision )
此方法返回一个字符串,包含以十进制指数记法表示的此 Number 值,有效数字的小数点前有一位数字,小数点后有 precision - 1 位数字,或者以十进制定点记法表示,有
precision 个有效数字。如果 precision 是 undefined ,它改为调用
ToString 。
当被调用时执行以下步骤:
设 x 为 ? ThisNumberValue (this
value)。
如果 precision 是 undefined ,返回 ! ToString (x )。
设 p 为 ? ToIntegerOrInfinity (precision )。
如果 x 不是 有限的 ,返回 Number::toString (x ,
10)。
如果 p < 1 或 p > 100,抛出 RangeError 异常。
设置 x 为 ℝ (x )。
设 s 为空字符串。
如果 x < 0,那么
设置 s 为代码单元 0x002D(连字符减号)。
设置 x 为 -x 。
如果 x = 0,那么
设 m 为由 p 个代码单元 0x0030(数字零)组成的字符串值。
设 e 为 0。
否则,
设 e 和 n 为 整数 ,使得
10p - 1 ≤ n < 10p
且 n × 10e - p + 1 -
x 尽可能接近零。如果有两组这样的 e 和 n ,选择使 n ×
10e - p + 1 更大的 e 和
n 。
设 m 为由 n 的十进制表示的数字组成的字符串值(按顺序,没有前导零)。
如果 e < -6 或 e ≥ p ,那么
断言 :e ≠ 0。
如果 p ≠ 1,那么
设 a 为 m 的第一个代码单元。
设 b 为 m 的其他 p - 1 个代码单元。
设置 m 为 a 、"." 和
b 的 字符串连接 。
如果 e > 0,那么
设 c 为代码单元 0x002B(加号)。
否则,
断言 :e
< 0。
设 c 为代码单元 0x002D(连字符减号)。
设置 e 为 -e 。
设 d 为由 e 的十进制表示的数字组成的字符串值(按顺序,没有前导零)。
返回 s 、m 、代码单元 0x0065(拉丁小写字母 E)、c 和
d 的 字符串连接 。
如果 e = p - 1,返回 s 和 m 的 字符串连接 。
如果 e ≥ 0,那么
设置 m 为 m 的前 e + 1 个代码单元、代码单元 0x002E(句号)和
m 的其余 p - (e + 1) 个代码单元的 字符串连接 。
否则,
设置 m 为代码单元 0x0030(数字零)、代码单元 0x002E(句号)、-(e + 1) 个代码单元
0x0030(数字零)和字符串 m 的 字符串连接 。
返回 s 和 m 的 字符串连接 。
21.1.3.6 Number.prototype.toString ( [ radix ] )
注
可选的 radix 应该是在从 2 𝔽 到
36 𝔽 的 包含区间 内的 整数
Number 值。如果 radix 是
undefined ,那么使用 10 𝔽 作为
radix 的值。
此方法在被调用时执行以下步骤:
设 x 为 ? ThisNumberValue (this
value)。
如果 radix 是 undefined ,设 radixMV 为 10。
否则,设 radixMV 为 ? ToIntegerOrInfinity (radix )。
如果 radixMV 不在从 2 到 36 的 包含区间 内,抛出
RangeError 异常。
返回 Number::toString (x ,
radixMV )。
此方法不是通用的;如果其 this 值 不是 Number 或 Number
对象,它会抛出 TypeError 异常。因此,它不能转移到其他类型的对象上用作方法。
此方法的 "length" 属性是 1 𝔽 。
21.1.3.7 Number.prototype.valueOf ( )
返回 ? ThisNumberValue (this
value)。
21.1.3.7.1 ThisNumberValue ( value )
抽象操作 ThisNumberValue 接受参数 value (一个 ECMAScript 语言值 ),并返回一个
包含 Number 的
正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
如果 value 是
Number ,返回 value 。
如果 value 是对象 且 value
有 [[NumberData]] 内部槽,那么
设 n 为 value .[[NumberData]] 。
断言 :n 是
Number 。
返回 n 。
抛出 TypeError 异常。
21.1.4 Number 实例的属性
Number 实例是从 Number 原型对象 继承属性的
普通对象 。Number 实例还有一个 [[NumberData]] 内部槽。[[NumberData]] 内部槽是此 Number
对象表示的 Number 值。
21.2 BigInt 对象
21.2.1 BigInt 构造器
BigInt 构造器 :
是 %BigInt% 。
是 全局对象 的 "BigInt" 属性的初始值。
当作为函数而不是作为 构造器 调用时,执行类型转换。
不打算与 new 操作符一起使用或被子类化。它可以用作类定义中 extends 子句的值,但对 BigInt 构造器 的
super 调用将导致异常。
21.2.1.1 BigInt ( value )
此函数在被调用时执行以下步骤:
如果 NewTarget 不是 undefined ,抛出 TypeError 异常。
设 prim 为 ? ToPrimitive (value ,
number )。
如果 prim 是
Number ,返回 ? NumberToBigInt (prim )。
否则,返回 ? ToBigInt (prim )。
21.2.1.1.1 NumberToBigInt ( number )
抽象操作 NumberToBigInt 接受参数 number (一个 Number),并返回一个 包含 BigInt 的
正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
如果 number 不是 整数 Number ,
抛出 RangeError 异常。
返回 ℤ (ℝ (number ))。
21.2.2 BigInt 构造器的属性
BigInt 构造器 :
21.2.2.1 BigInt.asIntN ( bits , bigint )
此函数在被调用时执行以下步骤:
设置 bits 为 ? ToIndex (bits )。
设置 bigint 为 ? ToBigInt (bigint )。
设 mod 为 ℝ (bigint ) modulo
2bits 。
如果 mod ≥ 2bits - 1 ,返回 ℤ (mod -
2bits );否则,返回 ℤ (mod )。
21.2.2.2 BigInt.asUintN ( bits , bigint )
此函数在被调用时执行以下步骤:
设置 bits 为 ? ToIndex (bits )。
设置 bigint 为 ? ToBigInt (bigint )。
返回 ℤ (ℝ (bigint )
modulo
2bits )。
21.2.2.3 BigInt.prototype
BigInt.prototype 的初始值是 BigInt 原型对象 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.2.3 BigInt 原型对象的属性
BigInt 原型对象 :
方法规范中的短语"此 BigInt 值"是指通过将方法调用的 this 值作为参数调用抽象操作 ThisBigIntValue 返回的结果。
21.2.3.1 BigInt.prototype.constructor
BigInt.prototype.constructor 的初始值是 %BigInt% 。
21.2.3.2 BigInt.prototype.toLocaleString ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范中的规定实现此方法。如果 ECMAScript 实现不包含 ECMA-402
API,则使用此方法的以下规范:
此方法产生一个字符串值,该值表示根据 宿主环境 当前区域设置的约定格式化的此 BigInt 值。此方法是 实现定义的 ,允许(但不鼓励)它返回与
toString 相同的内容。
此方法的可选参数的含义在 ECMA-402 规范中定义;不包含 ECMA-402 支持的实现不得将这些参数位置用于任何其他用途。
21.2.3.3 BigInt.prototype.toString ( [ radix ] )
注
可选的 radix 应该是在从 2 𝔽 到
36 𝔽 的 包含区间 内的 整数
Number 值。如果 radix 是
undefined ,那么使用 10 𝔽 作为
radix 的值。
此方法在被调用时执行以下步骤:
设 x 为 ? ThisBigIntValue (this
value)。
如果 radix 是 undefined ,设 radixMV 为 10。
否则,设 radixMV 为 ? ToIntegerOrInfinity (radix )。
如果 radixMV 不在从 2 到 36 的 包含区间 内,抛出
RangeError 异常。
返回 BigInt::toString (x ,
radixMV )。
此方法不是通用的;如果其 this 值 不是 BigInt 或 BigInt
对象,它会抛出 TypeError 异常。因此,它不能转移到其他类型的对象上用作方法。
21.2.3.4 BigInt.prototype.valueOf ( )
返回 ? ThisBigIntValue (this
value)。
21.2.3.4.1 ThisBigIntValue ( value )
抽象操作 ThisBigIntValue 接受参数 value (一个 ECMAScript 语言值 ),并返回一个
包含 BigInt 的
正常完成 或一个
抛出完成 。当被调用时执行以下步骤:
如果 value 是
BigInt ,返回 value 。
如果 value 是对象 且 value
有 [[BigIntData]] 内部槽,那么
断言 :value .[[BigIntData]] 是
BigInt 。
返回 value .[[BigIntData]] 。
抛出 TypeError 异常。
21.2.3.5 BigInt.prototype [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值是字符串值
"BigInt" 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
21.2.4 BigInt 实例的属性
BigInt 实例是从 BigInt 原型对象 继承属性的
普通对象 。BigInt 实例还有一个 [[BigIntData]] 内部槽。[[BigIntData]] 内部槽是此 BigInt
对象表示的 BigInt 值。
21.3 Math 对象
Math 对象:
是 %Math% 。
是 全局对象 的 "Math" 属性的初始值。
是一个 普通对象 。
有一个 [[Prototype]] 内部槽,其值是 %Object.prototype% 。
不是 函数对象 。
没有 [[Construct]] 内部方法;它不能与 new 操作符一起用作 构造器 。
没有 [[Call]] 内部方法;它不能作为函数被调用。
注
在此规范中,短语"x 的 Number 值 "具有在 6.1.6.1 中定义的技术含义。
21.3.1 Math 对象的值属性
21.3.1.1 Math.E
e (自然对数的底)的 Number 值 ,约为 2.7182818284590452354。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.3.1.2 Math.LN10
10 的自然对数的 Number 值 ,约为 2.302585092994046。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.3.1.3 Math.LN2
2 的自然对数的 Number
值 ,约为 0.6931471805599453。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.3.1.4 Math.LOG10E
e (自然对数的底)的以 10 为底的对数的 Number 值 ;此值约为 0.4342944819032518。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
注
Math.LOG10E 的值约为 Math.LN10 值的倒数。
21.3.1.5 Math.LOG2E
e (自然对数的底)的以 2 为底的对数的 Number 值 ;此值约为 1.4426950408889634。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
注
Math.LOG2E 的值约为 Math.LN2 值的倒数。
21.3.1.6 Math.PI
π(圆的周长与其直径的比值)的 Number 值 ,约为 3.1415926535897932。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.3.1.7 Math.SQRT1_2
½ 的平方根的 Number
值 ,约为 0.7071067811865476。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
注
Math.SQRT1_2 的值约为 Math.SQRT2 值的倒数。
21.3.1.8 Math.SQRT2
2 的平方根的 Number
值 ,约为 1.4142135623730951。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.3.1.9 Math [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值是字符串值
"Math" 。
此属性有特性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
21.3.2 Math 对象的函数属性
注
函数
acos、acosh、asin、asinh、atan、atanh、atan2、cbrt、cos、cosh、exp、expm1、hypot、log、log1p、log2、log10、pow、random、sin、sinh、tan
和 tanh
的行为在此处未被精确指定,除了要求对表示感兴趣的边界情况的某些参数值有特定结果。对于其他参数值,这些函数意图计算熟悉的数学函数结果的近似值,但在近似算法的选择上允许一定的灵活性。总的意图是实现者应该能够在给定硬件平台上为
ECMAScript 使用与该平台上 C 程序员可用的相同数学库。
虽然算法的选择留给实现,但建议(但不是本标准规定的)实现使用 IEEE 754-2019 算术的近似算法,这些算法包含在
fdlibm 中,这是来自 Sun Microsystems 的可自由分发的数学库(http://www.netlib.org/fdlibm )。
21.3.2.1 Math.abs ( x )
此函数返回 x 的绝对值;结果与 x 具有相同的量级但符号为正。
当被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,返回 NaN 。
如果 n 是 -0 𝔽 ,返回
+0 𝔽 。
如果 n 是 -∞ 𝔽 ,返回
+∞ 𝔽 。
如果 n < -0 𝔽 ,返回 -n 。
返回 n 。
21.3.2.2 Math.acos ( x )
此函数返回 x 的反余弦值。结果以弧度表示,在从
+0 𝔽 到 𝔽 (π) 的闭区间 内。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,n >
1 𝔽 ,或 n <
-1 𝔽 ,返回 NaN 。
如果 n 是 1 𝔽 ,返回
+0 𝔽 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的反余弦值。
21.3.2.3 Math.acosh ( x )
此函数返回 x 的反双曲余弦值。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN 或
+∞ 𝔽 ,返回 n 。
如果 n 是 1 𝔽 ,返回
+0 𝔽 。
如果 n < 1 𝔽 ,返回
NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的反双曲余弦值。
21.3.2.4 Math.asin ( x )
此函数返回 x 的反正弦值。结果以弧度表示,在从 𝔽 (-π / 2) 到 𝔽 (π / 2) 的闭区间 内。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n > 1 𝔽 或 n <
-1 𝔽 ,返回 NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的反正弦值。
21.3.2.5 Math.asinh ( x )
此函数返回 x 的反双曲正弦值。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是
+0 𝔽 或 -0 𝔽 ,返回
n 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的反双曲正弦值。
21.3.2.6 Math.atan ( x )
此函数返回 x 的反正切值。结果以弧度表示,在从 𝔽 (-π / 2) 到 𝔽 (π / 2) 的闭区间 内。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n 是 +∞ 𝔽 ,返回一个实现近似 的 Number 值,表示 π / 2。
如果 n 是 -∞ 𝔽 ,返回一个实现近似 的 Number 值,表示 -π / 2。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的反正切值。
21.3.2.7 Math.atanh ( x )
此函数返回 x 的反双曲正切值。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n > 1 𝔽 或 n <
-1 𝔽 ,返回 NaN 。
如果 n 是 1 𝔽 ,返回
+∞ 𝔽 。
如果 n 是 -1 𝔽 ,返回
-∞ 𝔽 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的反双曲正切值。
21.3.2.8 Math.atan2 ( y , x )
此函数返回参数 y 和 x 的商 y /
x 的反正切值,其中 y 和 x 的符号用于确定
结果的象限。请注意,对于双参数反正切函数,参数名为 y 的位于第一位而参数名为 x 的位于第二位是有意的和传统的。结果以弧度表示,在从 -π
到 +π 的闭区间 内。
它在被调用时执行以下步骤:
设 ny 为 ? ToNumber (y )。
设 nx 为 ? ToNumber (x )。
如果 ny 是 NaN 或 nx 是
NaN ,返回 NaN 。
如果 ny 是 +∞ 𝔽 ,则
如果 nx 是 +∞ 𝔽 ,返回一个实现近似 的 Number 值,表示
π / 4。
如果 nx 是 -∞ 𝔽 ,返回一个实现近似 的 Number 值,表示
3π / 4。
返回一个实现近似 的 Number 值,表示
π / 2。
如果 ny 是 -∞ 𝔽 ,则
如果 nx 是 +∞ 𝔽 ,返回一个实现近似 的 Number 值,表示
-π / 4。
如果 nx 是 -∞ 𝔽 ,返回一个实现近似 的 Number 值,表示
-3π / 4。
返回一个实现近似 的 Number 值,表示
-π / 2。
如果 ny 是 +0 𝔽 ,则
如果 nx > +0 𝔽 或 nx 是
+0 𝔽 ,返回
+0 𝔽 。
返回一个实现近似 的 Number 值,表示
π。
如果 ny 是 -0 𝔽 ,则
如果 nx > +0 𝔽 或 nx 是
+0 𝔽 ,返回
-0 𝔽 。
返回一个实现近似 的 Number 值,表示
-π。
断言 :
ny 是有限的 且既不是
+0 𝔽 也不是 -0 𝔽 。
如果 ny > +0 𝔽 ,则
如果 nx 是 +∞ 𝔽 ,返回
+0 𝔽 。
如果 nx 是 -∞ 𝔽 ,返回一个实现近似 的 Number 值,表示
π。
如果 nx 是 +0 𝔽 或
-0 𝔽 ,返回一个实现近似 的 Number 值,表示
π / 2。
如果 ny < -0 𝔽 ,则
如果 nx 是 +∞ 𝔽 ,返回
-0 𝔽 。
如果 nx 是 -∞ 𝔽 ,返回一个实现近似 的 Number 值,表示
-π。
如果 nx 是 +0 𝔽 或
-0 𝔽 ,返回一个实现近似 的 Number 值,表示
-π / 2。
断言 :
nx 是有限的 且既不是
+0 𝔽 也不是 -0 𝔽 。
设 r 为 abs (ℝ (ny ) / ℝ (nx )) 的反正切值。
如果 nx < -0 𝔽 ,则
如果 ny > +0 𝔽 ,设 r
为 π - r 。
否则,设 r 为 -π + r 。
否则,
如果 ny < -0 𝔽 ,设 r
为 -r 。
返回一个实现近似 的 Number 值,表示
r 。
21.3.2.9 Math.cbrt ( x )
此函数返回 x 的立方根。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是
+0 𝔽 或 -0 𝔽 ,返回
n 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的立方根。
21.3.2.10 Math.ceil ( x )
此函数返回不小于 x 的最小(最接近 -∞)整数 Number 值。如果 x 已经是一个整数
Number ,结果就是
x 。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是
+0 𝔽 或 -0 𝔽 ,返回
n 。
如果 n < -0 𝔽 且 n >
-1 𝔽 ,返回 -0 𝔽 。
如果 n 是一个整数 Number ,返回 n 。
返回不小于 n 的最小(最接近 -∞)整数 Number 值。
注意
Math.ceil(x) 的值与
-Math.floor(-x) 的值相同。
21.3.2.11 Math.clz32 ( x )
此函数在被调用时执行以下步骤:
设 n 为 ? ToUint32 (x )。
设 p 为 n 的无符号 32 位二进制表示中前导零位的数量。
返回 𝔽 (p )。
注意
如果 n 是 +0 𝔽 或
-0 𝔽 ,此方法返回
32 𝔽 。如果 n 的 32 位二进制编码的最高有效位是 1,此方法返回
+0 𝔽 。
21.3.2.12 Math.cos ( x )
此函数返回 x 的余弦值。参数以弧度表示。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 ,返回 NaN 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,返回 1 𝔽 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的余弦值。
21.3.2.13 Math.cosh ( x )
此函数返回 x 的双曲余弦值。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,返回 NaN 。
如果 n 是 +∞ 𝔽 或
-∞ 𝔽 ,返回 +∞ 𝔽 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,返回 1 𝔽 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的双曲余弦值。
注意
Math.cosh(x) 的值与
(Math.exp(x) + Math.exp(-x)) / 2 的值相同。
21.3.2.14 Math.exp ( x )
此函数返回 x 的指数函数(e 的 x 次幂,其中 e 是自然对数的底)。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN 或
+∞ 𝔽 ,返回 n 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,返回 1 𝔽 。
如果 n 是 -∞ 𝔽 ,返回
+0 𝔽 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的指数函数。
21.3.2.15 Math.expm1 ( x )
此函数返回从 x 的指数函数(e 的 x 次幂,其中 e 是自然对数的底)中减去 1
的结果。该结果以一种即使当 x 的值接近 0 时也很准确的方式计算。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,-0 𝔽 ,或
+∞ 𝔽 之一,返回 n 。
如果 n 是 -∞ 𝔽 ,返回
-1 𝔽 。
设 exp 为 ℝ (n ) 的指数函数。
返回一个实现近似 的 Number 值,表示
exp - 1。
21.3.2.16 Math.floor ( x )
此函数返回不大于 x 的最大(最接近 +∞)整数 Number 值。如果 x 已经是一个整数
Number ,结果就是 x 。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是
+0 𝔽 或 -0 𝔽 ,返回
n 。
如果 n < 1 𝔽 且 n >
+0 𝔽 ,返回 +0 𝔽 。
如果 n 是一个整数 Number ,返回 n 。
返回不大于 n 的最大(最接近 +∞)整数 Number 值。
注意
Math.floor(x) 的值与
-Math.ceil(-x) 的值相同。
21.3.2.17 Math.fround ( x )
此函数在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,返回 NaN 。
如果 n 是 +0 𝔽 ,
-0 𝔽 ,+∞ 𝔽 ,或
-∞ 𝔽 之一,返回 n 。
设 n32 为使用 roundTiesToEven 模式将 n 转换为 IEEE
754-2019 binary32 格式的结果。
设 n64 为将 n32 转换为 IEEE
754-2019 binary64 格式的结果。
返回对应于 n64 的 ECMAScript Number 值。
21.3.2.18 Math.f16round ( x )
此函数在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,返回 NaN 。
如果 n 是 +0 𝔽 ,
-0 𝔽 ,+∞ 𝔽 ,或
-∞ 𝔽 之一,返回 n 。
设 n16 为使用 roundTiesToEven 模式将 n 转换为 IEEE
754-2019 binary16 格式的结果。
设 n64 为将 n16 转换为 IEEE
754-2019 binary64 格式的结果。
返回对应于 n64 的 ECMAScript Number 值。
注意
此操作与先转换为 binary32 再转换为 binary16 是不同的,因为可能存在双重舍入:例如,考虑数字 k =
1.00048828125000022204 𝔽 ,对于它,Math.f16round(k )
是 1.0009765625 𝔽 ,但
Math.f16round(Math.fround(k )) 是 1 𝔽 。
并非所有平台都提供从 binary64 转换为 binary16 的原生支持。有各种库可以提供此功能,包括 MIT 许可的 half 库。或者,可以首先在 roundTiesToEven 下从
binary64 转换为 binary32,然后检查结果是否可能导致不正确的双重舍入。可能导致问题的情况可以通过调整 binary32 值的尾数来明确处理,使其成为在
roundTiesToOdd 下执行初始转换时会产生的值。然后在 roundTiesToEven 下将调整后的值转换为 binary16 就会产生正确的值。
21.3.2.19 Math.hypot ( ...args )
给定零个或多个参数,此函数返回其参数的平方和的平方根。
它在被调用时执行以下步骤:
设 coerced 为一个新的空列表 。
对于 args 的每个元素 arg ,执行
设 n 为 ? ToNumber (arg )。
将 n 追加到 coerced 。
对于 coerced 的每个元素 number ,执行
如果 number 是 +∞ 𝔽 或
-∞ 𝔽 ,返回
+∞ 𝔽 。
设 onlyZero 为 true 。
对于 coerced 的每个元素 number ,执行
如果 number 是 NaN ,返回
NaN 。
如果 number 既不是 +0 𝔽 也不是
-0 𝔽 ,设 onlyZero 为
false 。
如果 onlyZero 是 true ,返回
+0 𝔽 。
返回一个实现近似 的 Number 值,表示
coerced 元素的数学值 的平方和的平方根。
此函数的 "length" 属性是
2 𝔽 。
注意
实现应当注意避免当此函数以两个或更多参数调用时,在朴素实现中容易发生的溢出和下溢导致的精度损失。
21.3.2.20 Math.imul ( x , y )
此函数在被调用时执行以下步骤:
设 a 为 ℝ (?
ToUint32 (x ))。
设 b 为 ℝ (?
ToUint32 (y ))。
设 product 为 (a × b ) 模 232 。
如果 product ≥ 231 ,返回 𝔽 (product -
232 );否则返回 𝔽 (product )。
21.3.2.21 Math.log ( x )
此函数返回 x 的自然对数。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN 或
+∞ 𝔽 ,返回 n 。
如果 n 是 1 𝔽 ,返回
+0 𝔽 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,返回 -∞ 𝔽 。
如果 n < -0 𝔽 ,返回
NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的自然对数。
21.3.2.22 Math.log1p ( x )
此函数返回 1 + x 的自然对数。该结果以一种即使当 x 的值接近零时也很准确的方式计算。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,-0 𝔽 ,或
+∞ 𝔽 之一,返回 n 。
如果 n 是 -1 𝔽 ,返回
-∞ 𝔽 。
如果 n < -1 𝔽 ,返回
NaN 。
返回一个实现近似 的 Number 值,表示 1 +
ℝ (n )
的自然对数。
21.3.2.23 Math.log10 ( x )
此函数返回 x 的以 10 为底的对数。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN 或
+∞ 𝔽 ,返回 n 。
如果 n 是 1 𝔽 ,返回
+0 𝔽 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,返回 -∞ 𝔽 。
如果 n < -0 𝔽 ,返回
NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的以 10
为底的对数。
21.3.2.24 Math.log2 ( x )
此函数返回 x 的以 2 为底的对数。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN 或
+∞ 𝔽 ,返回 n 。
如果 n 是 1 𝔽 ,返回
+0 𝔽 。
如果 n 是 +0 𝔽 或
-0 𝔽 ,返回 -∞ 𝔽 。
如果 n < -0 𝔽 ,返回
NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的以 2
为底的对数。
21.3.2.25 Math.max ( ...args )
给定零个或多个参数,此函数对每个参数调用 ToNumber 并返回结果值中的最大值。
它在被调用时执行以下步骤:
设 coerced 为一个新的空列表 。
对于 args 的每个元素 arg ,执行
设 n 为 ? ToNumber (arg )。
将 n 追加到 coerced 。
设 highest 为 -∞ 𝔽 。
对于 coerced 的每个元素 number ,执行
如果 number 是 NaN ,返回
NaN 。
如果 number 是 +0 𝔽 且
highest 是 -0 𝔽 ,设
highest 为 +0 𝔽 。
如果 number > highest ,设 highest 为
number 。
返回 highest 。
注意
确定最大值的值比较使用 IsLessThan 算法完成,但是
+0 𝔽 被认为大于
-0 𝔽 。
此函数的 "length" 属性是
2 𝔽 。
21.3.2.26 Math.min ( ...args )
给定零个或多个参数,此函数对每个参数调用 ToNumber 并返回结果值中的最小值。
它在被调用时执行以下步骤:
设 coerced 为一个新的空列表 。
对于 args 的每个元素 arg ,执行
设 n 为 ? ToNumber (arg )。
将 n 追加到 coerced 。
设 lowest 为 +∞ 𝔽 。
对于 coerced 的每个元素 number ,执行
如果 number 是 NaN ,返回
NaN 。
如果 number 是 -0 𝔽 且
lowest 是 +0 𝔽 ,设
lowest 为 -0 𝔽 。
如果 number < lowest ,设 lowest 为
number 。
返回 lowest 。
注意
确定最小值的值比较使用 IsLessThan 算法完成,但是
+0 𝔽 被认为大于
-0 𝔽 。
此函数的 "length" 属性是
2 𝔽 。
21.3.2.27 Math.pow ( base , exponent )
此函数在被调用时执行以下步骤:
设 base 为 ? ToNumber (base )。
设 exponent 为 ? ToNumber (exponent )。
返回 Number::exponentiate (base ,
exponent )。
21.3.2.28 Math.random ( )
此函数返回一个具有正号的 Number 值,大于或等于
+0 𝔽 但严格小于 1 𝔽 ,
使用实现定义 的算法或策略随机或伪随机选择,在该范围内具有近似均匀分布。
为不同领域 创建的每个
Math.random 函数必须从连续调用中产生不同的值序列。
21.3.2.29 Math.round ( x )
此函数返回最接近 x 且为整数的 Number 值。如果两个整数
Number 与 x 的距离相等,则结果是更接近 +∞ 的 Number 值。如果 x
已经是整数,结果就是
x 。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是一个整数
Number ,返回 n 。
如果 n < 0.5 𝔽 且 n >
+0 𝔽 ,返回 +0 𝔽 。
如果 n < -0 𝔽 且 n ≥
-0.5 𝔽 ,返回 -0 𝔽 。
返回最接近 n 的整数 Number ,在平局的情况下优选更接近 +∞ 的 Number。
注意 1
Math.round(3.5) 返回 4,但 Math.round(-3.5) 返回 -3。
注意 2
Math.round(x) 的值并不总是与
Math.floor(x + 0.5) 的值相同。当 x 是
-0 𝔽 或 x 小于
-0 𝔽 但大于或等于
-0.5 𝔽 时,Math.round(x) 返回
-0 𝔽 ,但 Math.floor(x + 0.5) 返回
+0 𝔽 。Math.round(x) 也可能因为计算
x + 0.5 时的内部舍入而与
Math.floor(x + 0.5) 的值不同。
21.3.2.30 Math.sign ( x )
此函数返回 x 的符号,指示 x 是正数、负数还是零。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n < -0 𝔽 ,返回
-1 𝔽 。
返回 1 𝔽 。
21.3.2.31 Math.sin ( x )
此函数返回 x 的正弦值。参数以弧度表示。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n 是 +∞ 𝔽 或
-∞ 𝔽 ,返回 NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的正弦值。
21.3.2.32 Math.sinh ( x )
此函数返回 x 的双曲正弦值。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是
+0 𝔽 或 -0 𝔽 ,返回
n 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的双曲正弦值。
注意
Math.sinh(x) 的值与
(Math.exp(x) - Math.exp(-x)) / 2 的值相同。
21.3.2.33 Math.sqrt ( x )
此函数返回 x 的平方根。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,-0 𝔽 ,或
+∞ 𝔽 之一,返回 n 。
如果 n < -0 𝔽 ,返回
NaN 。
返回 𝔽 (ℝ (n ) 的平方根)。
21.3.2.34 Math.tan ( x )
此函数返回 x 的正切值。参数以弧度表示。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n 是 +∞ 𝔽 或
-∞ 𝔽 ,返回 NaN 。
返回一个实现近似 的 Number 值,表示
ℝ (n ) 的正切值。
21.3.2.35 Math.tanh ( x )
此函数返回 x 的双曲正切值。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 是 NaN ,
+0 𝔽 ,或 -0 𝔽 之一,返回
n 。
如果 n 是 +∞ 𝔽 ,返回
1 𝔽 。
如果 n 是 -∞ 𝔽 ,返回
-1 𝔽 。
返回一个实现近似 的 Number 值,表示
ℝ (n )
的双曲正切值。
注意
Math.tanh(x) 的值与
(Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x)) 的值相同。
21.3.2.36 Math.trunc ( x )
此函数返回数字 x 的整数部分,移除任何小数位。如果 x 已经是整数,结果就是 x 。
它在被调用时执行以下步骤:
设 n 为 ? ToNumber (x )。
如果 n 不是有限的 或 n 是
+0 𝔽 或 -0 𝔽 ,返回
n 。
如果 n < 1 𝔽 且 n >
+0 𝔽 ,返回 +0 𝔽 。
如果 n < -0 𝔽 且 n >
-1 𝔽 ,返回 -0 𝔽 。
返回最接近 n 且朝向 +0 𝔽 方向的整数
Number 。
21.4 Date 对象
21.4.1 Date 对象概述和抽象操作的定义
以下抽象操作 对时间值 (在 21.4.1.1
中定义)进行操作。注意,在任何情况下,如果这些函数的任何参数是 NaN ,结果将是
NaN 。
21.4.1.1 时间值和时间范围
ECMAScript 中的时间测量类似于 POSIX 中的时间测量,特别是共享以前推格里高利历为基础的定义,以 1970 年 1 月 1 日 UTC 午夜开始为纪元 ,并且将每一天计算为恰好 86,400 秒(每秒为 1000 毫秒)。
ECMAScript 时间值 是一个
Number ,要么是一个有限 的整数
Number ,表示精确到毫秒的时间瞬间,要么是 NaN ,表示没有特定的时间瞬间。是
24 × 60 × 60 × 1000 = 86,400,000 的倍数(即,对于某个整数 d 为
86,400,000 ×
d )的时间值表示在纪元 之后 d 个完整 UTC 天(负 d 表示在纪元 之前)的 UTC
天开始时的瞬间。任何其他有限 时间值
t 相对于最大的前导时间值 s (其为这样的倍数)定义,并表示在与 s 相同的 UTC 天内但在它之后
(t
- s ) 毫秒发生的瞬间。
时间值不考虑 UTC 闰秒——没有时间值表示正闰秒内的瞬间,并且有时间值表示被负闰秒从 UTC 时间线中移除的瞬间。然而,时间值的定义仍然产生与 UTC
的分段对齐,仅在闰秒边界处有不连续性,在闰秒之外没有差异。
Number 可以精确表示从 -9,007,199,254,740,992 到
9,007,199,254,740,992 的所有整数 (21.1.2.8 和 21.1.2.6 )。时间值支持稍小的范围,从
-8,640,000,000,000,000 到 8,640,000,000,000,000 毫秒。这产生了一个支持的时间值范围,恰好相对于 1970 年 1 月 1 日 UTC
午夜为 -100,000,000 天到 100,000,000 天。
1970 年 1 月 1 日 UTC 午夜开始的确切时刻由时间值 +0 𝔽 表示。
注意
在前推格里高利历中,闰年恰好是那些既能被 4 整除,又能被 400 整除或不能被 100 整除的年份。
前推格里高利历的 400 年周期包含 97 个闰年。这产生平均每年 365.2425 天,即 31,556,952,000 毫秒。因此,Number
能以毫秒精度精确表示的最大范围大约是相对于 1970 年的 -285,426 到 285,426 年。本节中指定的时间值支持的较小范围大约是相对于 1970 年的
-273,790 到 273,790 年。
21.4.1.2 时间相关常量
这些常量被以下部分的算法引用。
HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
msPerSecond = 1000 𝔽
21.4.1.3 Day ( t )
抽象操作 Day 接受参数 t (一个有限 的时间值 )并返回一个整数
Number 。它返回 t 所在天的天数。它在被调用时执行以下步骤:
返回 𝔽 (floor (ℝ (t / msPerDay )))。
21.4.1.4 TimeWithinDay ( t )
抽象操作 TimeWithinDay 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 (包含)到 msPerDay (不包含)的区间 内的整数
Number 。它返回自 t 所在天开始以来的毫秒数。它在被调用时执行以下步骤:
返回 𝔽 (ℝ (t ) 模
ℝ (msPerDay ))。
21.4.1.5 DaysInYear ( y )
抽象操作 DaysInYear 接受参数 y (一个整数
Number )并返回 365 𝔽 或
366 𝔽 。它返回年份 y 中的天数。闰年有 366 天;所有其他年份有 365
天。它在被调用时执行以下步骤:
设 ry 为 ℝ (y )。
如果 (ry 模 400) = 0,返回
366 𝔽 。
如果 (ry 模 100) = 0,返回
365 𝔽 。
如果 (ry 模 4) = 0,返回
366 𝔽 。
返回 365 𝔽 。
21.4.1.6 DayFromYear ( y )
抽象操作 DayFromYear 接受参数 y (一个整数
Number )并返回一个整数 Number 。它返回年份 y
第一天的天数。它在被调用时执行以下步骤:
设 ry 为 ℝ (y )。
注意:在以下步骤中,
numYears1 、numYears4 、numYears100 和
numYears400 分别表示在纪元 和年份 y 开始之间发生的可被 1、4、100 和 400
整除的年数。如果 y 在纪元 之前,该数字为负数。
设 numYears1 为 (ry - 1970)。
设 numYears4 为 floor ((ry - 1969) / 4)。
设 numYears100 为 floor ((ry - 1901) / 100)。
设 numYears400 为 floor ((ry - 1601) / 400)。
返回 𝔽 (365 ×
numYears1 + numYears4 - numYears100 +
numYears400 )。
21.4.1.7 TimeFromYear ( y )
抽象操作 TimeFromYear 接受参数 y (一个整数
Number )并返回一个时间值 。它返回年份
y 开始的时间值 。它在被调用时执行以下步骤:
返回 msPerDay × DayFromYear (y )。
21.4.1.8 YearFromTime ( t )
抽象操作 YearFromTime 接受参数 t (一个有限 的时间值 )并返回一个整数
Number 。它返回 t 所在的年份。它在被调用时执行以下步骤:
返回最大的整数 Number y (最接近 +∞),使得
TimeFromYear (y ) ≤
t 。
21.4.1.9 DayWithinYear ( t )
抽象操作 DayWithinYear 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 365 𝔽 的闭区间 内的整数
Number 。它在被调用时执行以下步骤:
返回 Day (t ) - DayFromYear (YearFromTime (t ))。
21.4.1.10 InLeapYear ( t )
抽象操作 InLeapYear 接受参数 t (一个有限 的时间值 )并返回
+0 𝔽 或 1 𝔽 。如果 t
在闰年内,它返回
1 𝔽 ,否则返回 +0 𝔽 。它在被调用时执行以下步骤:
如果 DaysInYear (YearFromTime (t )) 是
366 𝔽 ,返回 1 𝔽 ;否则返回
+0 𝔽 。
21.4.1.11 MonthFromTime ( t )
抽象操作 MonthFromTime 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 11 𝔽 的闭区间 内的整数
Number 。它返回一个标识 t 所在月份的 Number。月份值
+0 𝔽 指定一月;1 𝔽
指定二月;2 𝔽 指定三月;
3 𝔽 指定四月;4 𝔽
指定五月;5 𝔽 指定六月;
6 𝔽 指定七月;7 𝔽
指定八月;8 𝔽 指定九月;
9 𝔽 指定十月;10 𝔽
指定十一月;11 𝔽 指定十二月。注意
MonthFromTime(+0 𝔽 ) =
+0 𝔽 ,对应于 1970 年 1 月 1 日星期四。它在被调用时执行以下步骤:
设 inLeapYear 为 InLeapYear (t )。
设 dayWithinYear 为 DayWithinYear (t )。
如果 dayWithinYear < 31 𝔽 ,返回
+0 𝔽 。
如果 dayWithinYear < 59 𝔽 +
inLeapYear ,返回 1 𝔽 。
如果 dayWithinYear < 90 𝔽 +
inLeapYear ,返回 2 𝔽 。
如果 dayWithinYear < 120 𝔽 +
inLeapYear ,返回 3 𝔽 。
如果 dayWithinYear < 151 𝔽 +
inLeapYear ,返回 4 𝔽 。
如果 dayWithinYear < 181 𝔽 +
inLeapYear ,返回 5 𝔽 。
如果 dayWithinYear < 212 𝔽 +
inLeapYear ,返回 6 𝔽 。
如果 dayWithinYear < 243 𝔽 +
inLeapYear ,返回 7 𝔽 。
如果 dayWithinYear < 273 𝔽 +
inLeapYear ,返回 8 𝔽 。
如果 dayWithinYear < 304 𝔽 +
inLeapYear ,返回 9 𝔽 。
如果 dayWithinYear < 334 𝔽 +
inLeapYear ,返回 10 𝔽 。
断言 :
dayWithinYear < 365 𝔽 +
inLeapYear 。
返回 11 𝔽 。
21.4.1.12 DateFromTime ( t )
抽象操作 DateFromTime 接受参数 t (一个有限 的时间值 )并返回一个在从
1 𝔽 到 31 𝔽 的闭区间 内的整数
Number 。它返回 t 所在月份的日期。它在被调用时执行以下步骤:
设 inLeapYear 为 InLeapYear (t )。
设 dayWithinYear 为 DayWithinYear (t )。
设 month 为 MonthFromTime (t )。
如果 month 是 +0 𝔽 ,返回
dayWithinYear + 1 𝔽 。
如果 month 是 1 𝔽 ,返回
dayWithinYear - 30 𝔽 。
如果 month 是 2 𝔽 ,返回
dayWithinYear - 58 𝔽 -
inLeapYear 。
如果 month 是 3 𝔽 ,返回
dayWithinYear - 89 𝔽 -
inLeapYear 。
如果 month 是 4 𝔽 ,返回
dayWithinYear - 119 𝔽 -
inLeapYear 。
如果 month 是 5 𝔽 ,返回
dayWithinYear - 150 𝔽 -
inLeapYear 。
如果 month 是 6 𝔽 ,返回
dayWithinYear - 180 𝔽 -
inLeapYear 。
如果 month 是 7 𝔽 ,返回
dayWithinYear - 211 𝔽 -
inLeapYear 。
如果 month 是 8 𝔽 ,返回
dayWithinYear - 242 𝔽 -
inLeapYear 。
如果 month 是 9 𝔽 ,返回
dayWithinYear - 272 𝔽 -
inLeapYear 。
如果 month 是 10 𝔽 ,返回
dayWithinYear - 303 𝔽 -
inLeapYear 。
断言 :
month 是 11 𝔽 。
返回 dayWithinYear - 333 𝔽 -
inLeapYear 。
21.4.1.13 WeekDay ( t )
抽象操作 WeekDay 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 6 𝔽 的闭区间 内的整数
Number 。它返回一个标识 t 所在星期几的 Number。星期值
+0 𝔽 指定星期日;1 𝔽
指定星期一;2 𝔽 指定星期二;
3 𝔽 指定星期三;4 𝔽
指定星期四;5 𝔽 指定星期五;
6 𝔽 指定星期六。注意 WeekDay(+0 𝔽 ) =
4 𝔽 ,对应于 1970 年 1 月 1 日星期四。它在被调用时执行以下步骤:
返回 𝔽 (ℝ (Day (t ) +
4 𝔽 ) 模 7)。
21.4.1.14 HourFromTime ( t )
抽象操作 HourFromTime 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 23 𝔽 的闭区间 内的整数
Number 。它返回 t 所在天的小时。它在被调用时执行以下步骤:
返回 𝔽 (floor (ℝ (t / msPerHour )) 模 HoursPerDay )。
21.4.1.15 MinFromTime ( t )
抽象操作 MinFromTime 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 59 𝔽 的闭区间 内的整数
Number 。它返回 t 所在小时的分钟。它在被调用时执行以下步骤:
返回 𝔽 (floor (ℝ (t / msPerMinute )) 模 MinutesPerHour )。
21.4.1.16 SecFromTime ( t )
抽象操作 SecFromTime 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 59 𝔽 的闭区间 内的整数
Number 。它返回 t 所在分钟的秒数。它在被调用时执行以下步骤:
返回 𝔽 (floor (ℝ (t / msPerSecond )) 模 SecondsPerMinute )。
21.4.1.17 msFromTime ( t )
抽象操作 msFromTime 接受参数 t (一个有限 的时间值 )并返回一个在从
+0 𝔽 到 999 𝔽 的闭区间 内的整数
Number 。它返回 t 所在秒的毫秒数。它在被调用时执行以下步骤:
返回 𝔽 (ℝ (t ) 模
ℝ (msPerSecond ))。
21.4.1.18 GetUTCEpochNanoseconds ( year ,
month , day , hour , minute , second ,
millisecond , microsecond , nanosecond )
抽象操作 GetUTCEpochNanoseconds 接受参数 year (一个整数 )、
month (一个在 1 到 12 的闭区间 内的整数 )、day (一个在 1 到 31
的闭区间 内的整数 )、hour (一个在 0 到 23
的闭区间 内的整数 )、minute (一个在 0 到 59
的闭区间 内的整数 )、second (一个在 0 到 59
的闭区间 内的整数 )、millisecond (一个在 0 到 999
的闭区间 内的整数 )、microsecond (一个在 0 到 999
的闭区间 内的整数 )和 nanosecond (一个在 0 到 999
的闭区间 内的整数 )并返回一个 BigInt。返回值表示自纪元 以来对应于给定 ISO 8601 日历日期和
UTC 挂钟时间的纳秒数。它在被调用时执行以下步骤:
设 date 为 MakeDay (𝔽 (year ), 𝔽 (month - 1),
𝔽 (day ))。
设 time 为 MakeTime (𝔽 (hour ), 𝔽 (minute ),
𝔽 (second ), 𝔽 (millisecond ))。
设 ms 为 MakeDate (date ,
time )。
断言 :
ms 是一个整数 Number 。
返回 ℤ (ℝ (ms ) ×
106 + microsecond × 103 + nanosecond )。
21.4.1.19 时区标识符
ECMAScript 中的时区由时区标识符 表示,它们是完全由在从
0x0000 到 0x007F 的闭区间 内的代码单元组成的字符串。ECMAScript 实现支持的时区可能是可用命名时区 ,由 AvailableNamedTimeZoneIdentifiers
返回的时区标识符记录 的 [[Identifier]] 字段表示,或者是偏移时区 ,由 IsTimeZoneOffsetString 返回
true 的字符串表示。
主要时区标识符 是可用命名时区的首选标识符。
非主要时区标识符 是不是主要时区标识符的可用命名时区标识符。
可用命名时区标识符 要么是主要时区标识符,要么是非主要时区标识符。
每个可用命名时区标识符恰好与一个可用命名时区关联。
每个可用命名时区恰好与一个主要时区标识符和零个或多个非主要时区标识符关联。
ECMAScript 实现必须支持标识符为 "UTC" 的可用命名时区,该标识符必须是 UTC 时区的主要时区标识符。
此外,实现可以支持任意数量的其他可用命名时区。
遵循 ECMA-402 国际化 API 规范中描述的时区要求的实现称为时区感知 的。
时区感知实现必须支持对应于 IANA 时区数据库的 Zone 和 Link 名称的可用命名时区,并且仅支持这些名称。
在时区感知实现中,主要时区标识符是 Zone 名称,非主要时区标识符是 Link 名称,分别在 IANA 时区数据库中,除非被 ECMA-402 规范中指定的 AvailableNamedTimeZoneIdentifiers
特别覆盖。
不支持整个 IANA 时区数据库的实现仍然建议使用 IANA 时区数据库名称作为标识符来表示时区。
21.4.1.20 GetNamedTimeZoneEpochNanoseconds (
timeZoneIdentifier , year , month , day ,
hour , minute , second , millisecond ,
microsecond , nanosecond )
实现定义 的抽象操作
GetNamedTimeZoneEpochNanoseconds 接受参数
timeZoneIdentifier (一个字符串)、year (一个整数 )、month (一个在 1 到 12
的闭区间 内的整数 )、day (一个在 1 到 31
的闭区间 内的整数 )、hour (一个在 0 到 23
的闭区间 内的整数 )、minute (一个在 0 到 59
的闭区间 内的整数 )、second (一个在 0 到 59
的闭区间 内的整数 )、millisecond (一个在 0 到 999
的闭区间 内的整数 )、microsecond (一个在 0 到 999
的闭区间 内的整数 )和 nanosecond (一个在 0 到 999
的闭区间 内的整数 )并返回一个 BigInt 的列表 。
返回的列表 中的每个值表示自纪元 以来对应于给定 ISO 8601 日历日期和在由
timeZoneIdentifier 标识的命名时区中的挂钟时间的纳秒数。
当输入表示由于负时区转换(例如夏令时结束或由于时区规则变更导致时区偏移减少)而多次出现的本地时间时,返回的列表 将有多个元素,并将按数值升序排序。
当输入表示由于正时区转换(例如夏令时开始或由于时区规则变更导致时区偏移增加)而跳过的本地时间时,返回的列表 将为空。
否则,返回的列表 将有一个元素。
GetNamedTimeZoneEpochNanoseconds 的默认实现,用于不包含任何时区本地政治规则的 ECMAScript 实现,在被调用时执行以下步骤:
断言 :
timeZoneIdentifier 是 "UTC" 。
设 epochNanoseconds 为 GetUTCEpochNanoseconds (year ,
month , day , hour , minute ,
second , millisecond , microsecond ,
nanosecond )。
返回 « epochNanoseconds »。
注意
时区感知 实现(建议所有其他实现也如此)需要使用
IANA 时区数据库 https://www.iana.org/time-zones/
的时区信息。
2017 年 11 月 5 日在 America/New_York 的凌晨 1:30 重复了两次,所以
GetNamedTimeZoneEpochNanoseconds("America/New_York" , 2017, 11, 5,
1, 30, 0, 0, 0, 0) 将返回一个长度为 2 的列表 ,其中第一个元素表示
05:30 UTC(对应于 UTC 偏移 -04:00 的 01:30 美国东部夏令时),第二个元素表示 06:30
UTC(对应于 UTC 偏移 -05:00 的 01:30 美国东部标准时间)。
2017 年 3 月 12 日在 America/New_York 的凌晨 2:30 不存在,所以
GetNamedTimeZoneEpochNanoseconds("America/New_York" , 2017, 3, 12,
2, 30, 0, 0, 0, 0) 将返回一个空的列表 。
21.4.1.21 GetNamedTimeZoneOffsetNanoseconds (
timeZoneIdentifier , epochNanoseconds )
实现定义 的抽象操作
GetNamedTimeZoneOffsetNanoseconds 接受参数 timeZoneIdentifier (一个字符串)和
epochNanoseconds (一个 BigInt)并返回一个整数 。
返回的整数 表示由
timeZoneIdentifier 标识的命名时区在对应于相对于纪元 的 epochNanoseconds 的瞬间的 UTC 偏移,均以纳秒为单位。
GetNamedTimeZoneOffsetNanoseconds 的默认实现,用于不包含任何时区本地政治规则的 ECMAScript 实现,在被调用时执行以下步骤:
断言 :
timeZoneIdentifier 是 "UTC" 。
返回 0。
注意
21.4.1.22 时区标识符记录
时区标识符记录 是一个记录 ,用于描述一个可用命名时区标识符 及其对应的主要时区标识符 。
时区标识符记录具有表 64 中列出的字段。
表 64:时区标识符记录 字段
字段名
值
含义
[[Identifier]]
一个字符串
实现支持的可用命名时区标识符 。
[[PrimaryIdentifier]]
一个字符串
[[Identifier]] 解析到的主要时区标识符 。
注意
如果 [[Identifier]] 是一个主要时区标识符 ,那么 [[Identifier]] 就是
[[PrimaryIdentifier]] 。
21.4.1.23 AvailableNamedTimeZoneIdentifiers ( )
实现定义 的抽象操作
AvailableNamedTimeZoneIdentifiers 不接受参数并返回一个时区标识符记录 的列表 。
其结果描述此实现中所有可用命名时区标识符 ,以及对应于每个可用命名时区标识符 的主要时区标识符 。
该列表 根据每个时区标识符记录 的 [[Identifier]] 字段排序。
时区感知 实现,包括所有实现 ECMA-402 国际化 API
的实现,必须按照 ECMA-402 规范中指定的方式实现 AvailableNamedTimeZoneIdentifiers 抽象操作。
对于不是时区感知 的实现,AvailableNamedTimeZoneIdentifiers
在被调用时执行以下步骤:
如果实现不包含任何时区的本地政治规则,那么
返回 « 时区标识符记录 {
[[Identifier]] : "UTC" , [[PrimaryIdentifier]] :
"UTC" } »。
设 identifiers 为按字典序代码单元顺序 排序的唯一可用命名时区标识符 的列表 。
设 result 为一个新的空列表 。
对于 identifiers 的每个元素 identifier ,执行
设 primary 为 identifier 。
如果 identifier 是此实现中的非主要时区标识符 并且
identifier 不是 "UTC" ,那么
设 primary 为与 identifier 关联的主要时区标识符 。
注意:实现可能需要迭代解析 identifier 以获得主要时区标识符 。
设 record 为时区标识符记录 {
[[Identifier]] :
identifier , [[PrimaryIdentifier]] :
primary }。
将 record 附加到 result 。
断言 :
result 包含一个时区标识符记录
r ,使得 r .[[Identifier]] 是
"UTC" 并且
r .[[PrimaryIdentifier]] 是
"UTC" 。
返回 result 。
21.4.1.24 SystemTimeZoneIdentifier ( )
实现定义 的抽象操作 SystemTimeZoneIdentifier
不接受参数并返回一个字符串。
它返回一个表示宿主环境 当前时区的字符串,该字符串要么是一个表示 UTC
偏移的字符串(IsTimeZoneOffsetString 对其返回
true ),要么是一个主要时区标识符 。
它在被调用时执行以下步骤:
如果实现仅支持 UTC 时区,返回 "UTC" 。
设 systemTimeZoneString 为表示宿主环境 当前时区的字符串,要么是一个主要时区标识符 ,要么是一个偏移时区 标识符。
返回 systemTimeZoneString 。
注意
为了确保实现在 Date 对象的方法中通常提供的功能级别,建议 SystemTimeZoneIdentifier 返回对应于宿主环境 时区设置的 IANA 时区名称(如果存在的话)。
GetNamedTimeZoneEpochNanoseconds
和 GetNamedTimeZoneOffsetNanoseconds
必须反映该时区中标准时间和夏令时的本地政治规则(如果存在这些规则)。
例如,如果宿主环境 是系统上的浏览器,用户选择了美国东部时间作为他们的时区,
SystemTimeZoneIdentifier 返回 "America/New_York" 。
21.4.1.25 LocalTime ( t )
抽象操作 LocalTime 接受参数 t (一个有限 的时间值 )并返回一个整数
Number 。
它将 t 从 UTC 转换为本地时间。
应该使用在 t 时刻生效的标准时间和夏令时的本地政治规则来按照本节规定的方式确定结果。
它在被调用时执行以下步骤:
设 systemTimeZoneIdentifier 为 SystemTimeZoneIdentifier ()。
如果 IsTimeZoneOffsetString (systemTimeZoneIdentifier )
是 true ,那么
设 offsetNs 为 ParseTimeZoneOffsetString (systemTimeZoneIdentifier )。
否则,
设 offsetNs 为 GetNamedTimeZoneOffsetNanoseconds (systemTimeZoneIdentifier ,
ℤ (ℝ (t ) ×
106 ))。
设 offsetMs 为 truncate (offsetNs /
106 )。
返回 t + 𝔽 (offsetMs )。
注意 1
注意 2
时区感知 实现(建议所有其他实现也如此)需要使用
IANA 时区数据库 https://www.iana.org/time-zones/
的时区信息。
注意 3
在负时区转换时,当有重复时间时(例如夏令时结束或时区调整减少),两个不同的输入时间值 t UTC 会转换为相同的本地时间 tlocal 。
LocalTime(UTC (t local ))
不一定总是等于 t local 。相应地,UTC (LocalTime(t UTC ))
不一定总是等于 t UTC 。
21.4.1.26 UTC ( t )
抽象操作 UTC 接受参数 t (一个 Number)并返回一个时间值 。
它将 t 从本地时间转换为 UTC 时间值 。
应该使用在 t 时刻生效的标准时间和夏令时的本地政治规则来按照本节规定的方式确定结果。
它在被调用时执行以下步骤:
如果 t 不是有限 的,返回 NaN 。
设 systemTimeZoneIdentifier 为 SystemTimeZoneIdentifier ()。
如果 IsTimeZoneOffsetString (systemTimeZoneIdentifier )
是 true ,那么
设 offsetNs 为 ParseTimeZoneOffsetString (systemTimeZoneIdentifier )。
否则,
设 possibleInstants 为 GetNamedTimeZoneEpochNanoseconds (systemTimeZoneIdentifier ,
ℝ (YearFromTime (t )),
ℝ (MonthFromTime (t ))
+ 1, ℝ (DateFromTime (t )),
ℝ (HourFromTime (t )),
ℝ (MinFromTime (t )),
ℝ (SecFromTime (t )),
ℝ (msFromTime (t )), 0,
0)。
注意:以下步骤确保当 t
表示在负时区转换时多次重复的本地时间(例如夏令时结束或由于时区规则变更导致时区偏移减少)或在正时区转换时跳过的本地时间(例如夏令时开始或由于时区规则变更导致时区偏移增加)时,t
使用转换前的时区偏移进行解释。
如果 possibleInstants 不为空,那么
设 disambiguatedInstant 为
possibleInstants [0]。
否则,
注意:t 表示在正时区转换时跳过的本地时间(例如由于夏令时开始或时区规则变更增加 UTC 偏移)。
设 possibleInstantsBefore 为
GetNamedTimeZoneEpochNanoseconds (systemTimeZoneIdentifier ,
ℝ (YearFromTime (tBefore )),
ℝ (MonthFromTime (tBefore ))
+ 1, ℝ (DateFromTime (tBefore )),
ℝ (HourFromTime (tBefore )),
ℝ (MinFromTime (tBefore )),
ℝ (SecFromTime (tBefore )),
ℝ (msFromTime (tBefore )),
0, 0),其中 tBefore 是小于 t 的最大整数 Number ,使得
possibleInstantsBefore 不为空(即,tBefore
表示转换前的最后一个本地时间)。
设 disambiguatedInstant 为
possibleInstantsBefore 的最后一个元素。
设 offsetNs 为 GetNamedTimeZoneOffsetNanoseconds (systemTimeZoneIdentifier ,
disambiguatedInstant )。
设 offsetMs 为 truncate (offsetNs /
106 )。
返回 t - 𝔽 (offsetMs )。
输入 t 名义上是一个时间值 ,但可以是任何 Number 值。
算法不得将 t 限制在时间值 范围内,以便可以支持对应于时间值 范围边界的输入,而不管本地 UTC 偏移如何。
例如,最大时间值 是 8.64 ×
1015 ,对应于 "+275760-09-13T00:00:00Z" 。
在本地时区偏移在该瞬间比 UTC 提前 1 小时的环境中,它由更大的输入 8.64 × 1015 + 3.6 ×
106 表示,对应于 "+275760-09-13T01:00:00+01:00" 。
如果实现中没有本地时间 t 的政治规则,结果就是 t ,因为 SystemTimeZoneIdentifier 返回
"UTC" ,GetNamedTimeZoneOffsetNanoseconds
返回 0。
注意 1
时区感知 实现(建议所有其他实现也如此)需要使用
IANA 时区数据库 https://www.iana.org/time-zones/
的时区信息。
2017 年 11 月 5 日在 America/New_York 的凌晨 1:30 重复了两次(回退),但必须解释为 1:30 AM UTC-04 而不是 1:30
AM UTC-05。
在 UTC(TimeClip (MakeDate (MakeDay (2017, 10, 5), MakeTime (1, 30, 0, 0))))
中,offsetMs 的值是 -4 × msPerHour 。
2017 年 3 月 12 日在 America/New_York 的凌晨 2:30 不存在,但必须解释为 2:30 AM UTC-05(相当于 3:30 AM
UTC-04)。
在 UTC(TimeClip (MakeDate (MakeDay (2017, 2, 12), MakeTime (2, 30, 0, 0))))
中,offsetMs 的值是 -5 × msPerHour 。
注意 2
UTC(LocalTime (t UTC ))
不一定总是等于 t UTC 。相应地,LocalTime (UTC(t local ))
不一定总是等于 t local 。
21.4.1.27 MakeTime ( hour , min ,
sec , ms )
抽象操作 MakeTime 接受参数 hour (一个 Number)、min (一个
Number)、sec (一个 Number)和 ms (一个 Number)并返回一个 Number。它
计算毫秒数。它在被调用时执行以下步骤:
如果 hour 不是有限 的,min 不是有限 的,
sec 不是有限 的,或 ms 不是有限 的,返回
NaN 。
设 h 为 𝔽 (! ToIntegerOrInfinity (hour ))。
设 m 为 𝔽 (! ToIntegerOrInfinity (min ))。
设 s 为 𝔽 (! ToIntegerOrInfinity (sec ))。
设 milli 为 𝔽 (! ToIntegerOrInfinity (ms ))。
返回 ((h × msPerHour + m × msPerMinute ) + s ×
msPerSecond ) + milli 。
注意
MakeTime 中的算术是浮点算术,它不满足结合律,所以操作必须按正确的顺序执行。
21.4.1.28 MakeDay ( year , month ,
date )
抽象操作 MakeDay 接受参数 year (一个 Number)、month
(一个 Number)和 date (一个 Number)并返回一个 Number。它计算天数。它在被调用时执行以下步骤:
如果 year 不是有限 的,month 不是有限 的,或
date 不是有限 的,返回 NaN 。
设 y 为 𝔽 (! ToIntegerOrInfinity (year ))。
设 m 为 𝔽 (! ToIntegerOrInfinity (month ))。
设 dt 为 𝔽 (! ToIntegerOrInfinity (date ))。
设 ym 为 y + 𝔽 (floor (ℝ (m ) / 12))。
如果 ym 不是有限 的,返回 NaN 。
设 mn 为 𝔽 (ℝ (m ) modulo 12)。
找到一个有限 的时间值
t ,使得 YearFromTime (t ) 是
ym ,MonthFromTime (t ) 是
mn ,并且 DateFromTime (t ) 是
1 𝔽 ;但如果这不可能(因为某些
参数超出范围),返回 NaN 。
返回 Day (t ) + dt -
1 𝔽 。
21.4.1.29 MakeDate ( day , time )
抽象操作 MakeDate 接受参数 day (一个 Number)和 time
(一个 Number)并返回一个 Number。它计算毫秒数。它在被调用时执行以下步骤:
如果 day 不是有限 的或 time 不是有限 的,返回
NaN 。
设 tv 为 day × msPerDay + time 。
如果 tv 不是有限 的,返回 NaN 。
返回 tv 。
21.4.1.30 MakeFullYear ( year )
抽象操作 MakeFullYear 接受参数 year (一个 Number)并返回一个整数
Number 或 NaN 。它返回与 year 的整数 部分关联的完整年份,将闭区间 0
到 99 中的任何值解释为自 1900 年开始以来的年数。为了与推算格里高利历保持一致,"完整年份"定义为自第 0 年(公元前 1
年)开始以来完整年份的有符号计数。它在被调用时执行以下步骤:
如果 year 是 NaN ,返回 NaN 。
设 truncated 为 ! ToIntegerOrInfinity (year )。
如果 truncated 在闭区间
0 到 99 中,返回 1900 𝔽 + 𝔽 (truncated )。
返回 𝔽 (truncated )。
21.4.1.31 TimeClip ( time )
抽象操作 TimeClip 接受参数 time (一个 Number)并返回一个
Number。它计算毫秒数。它在被调用时执行以下步骤:
如果 time 不是有限 的,返回 NaN 。
如果 abs (ℝ (time )) > 8.64 × 1015 ,
返回 NaN 。
返回 𝔽 (!
ToIntegerOrInfinity (time ))。
21.4.1.32 日期时间字符串格式
ECMAScript 基于 ISO 8601 日历日期扩展格式的简化版本定义了日期时间的字符串交换格式。格式如下:
YYYY-MM-DDTHH:mm:ss.sssZ
其中各元素如下:
YYYY
是推算格里高利历中的年份,作为从 0000 到 9999 的四位十进制数字,或作为由 "+" 或
"-" 后跟六位十进制数字的扩展年份 。
-
"-" (连字符)在字符串中字面出现两次。
MM
是一年中的月份,作为从 01(一月)到 12(十二月)的两位十进制数字。
DD
是一个月中的日期,作为从 01 到 31 的两位十进制数字。
T
"T" 在字符串中字面出现,表示时间元素的开始。
HH
是自午夜以来经过的完整小时数,作为从 00 到 24 的两位十进制数字。
:
":" (冒号)在字符串中字面出现两次。
mm
是自小时开始以来的完整分钟数,作为从 00 到 59 的两位十进制数字。
ss
是自分钟开始以来的完整秒数,作为从 00 到 59 的两位十进制数字。
.
"." (点)在字符串中字面出现。
sss
是自秒开始以来的完整毫秒数,作为三位十进制数字。
Z
是 UTC 偏移表示,指定为 "Z" (对于无偏移的 UTC)或作为 "+"
或
"-" 后跟时间表达式 HH:mm(时区偏移字符串格式 的子集,分别用于指示本地时间早于或晚于
UTC)
此格式包括仅日期形式:
YYYY
YYYY-MM
YYYY-MM-DD
它还包括"日期时间"形式,由上述仅日期形式之一紧接一个以下时间形式(可附加可选的 UTC 偏移表示)组成:
THH:mm
THH:mm:ss
THH:mm:ss.sss
包含超出边界或不符合要求元素的字符串不是此格式的有效实例。
注意 1
由于每一天都以午夜开始和结束,00:00
和 24:00
这两种表示法可用于区分可能与一个日期关联的两个午夜。这意味着以下两种表示法指的是完全相同的时间点:1995-02-04T24:00 和
1995-02-05T00:00。将后一种形式解释为"日历日的结束"与 ISO 8601
一致,尽管该规范将其保留用于描述时间间隔,并且不允许在单个时间点的表示中使用。
注意 2
不存在指定民用时区缩写(如 CET、EST 等)的国际标准,有时同一缩写甚至用于两个非常不同的时区。出于这个原因,ISO 8601 和此格式都指定时区偏移的数字表示。
21.4.1.32.1 扩展年份
涵盖从 1970 年 1 月 1 日向前或向后约 273,790 年的完整时间值 范围(21.4.1.1 )需要表示 0 之前或 9999
之后的年份。ISO 8601 允许扩展年份表示,但仅在信息交换伙伴相互同意的情况下。在简化的 ECMAScript 格式中,这种扩展年份表示应有 6 位数字,并且始终以 + 或
- 符号为前缀。年份 0 被认为是正数,必须以 + 符号为前缀。将年份 0 表示为 -000000 是无效的。匹配带有扩展年份的日期时间字符串格式 的字符串,如果表示超出时间值 范围的时间瞬间,将被 Date.parse 视为不可识别,并导致该函数返回
NaN ,而不回退到实现特定的行为或启发式。
注意
带有扩展年份的日期时间值示例:
-271821-04-20T00:00:00Z
公元前 271822 年
-000001-01-01T00:00:00Z
公元前 2 年
+000000-01-01T00:00:00Z
公元前 1 年
+000001-01-01T00:00:00Z
公元 1 年
+001970-01-01T00:00:00Z
公元 1970 年
+002009-12-15T00:00:00Z
公元 2009 年
+275760-09-13T00:00:00Z
公元 275760 年
21.4.1.33 时区偏移字符串格式
ECMAScript 定义了一个来源于 ISO 8601 的 UTC 偏移字符串交换格式。
该格式由以下语法描述。
语法
UTCOffset :::
ASCIISign
Hour
ASCIISign
Hour
HourSubcomponents [+Extended]
ASCIISign
Hour
HourSubcomponents [~Extended]
ASCIISign :::
one of + -
Hour :::
0
DecimalDigit
1
DecimalDigit
20
21
22
23
HourSubcomponents [Extended]
:::
TimeSeparator [?Extended]
MinuteSecond
TimeSeparator [?Extended]
MinuteSecond
TimeSeparator [?Extended]
MinuteSecond
TemporalDecimalFraction opt
TimeSeparator [Extended]
::: [+Extended]
:
[~Extended]
[empty]
MinuteSecond :::
0
DecimalDigit
1
DecimalDigit
2
DecimalDigit
3
DecimalDigit
4
DecimalDigit
5
DecimalDigit
TemporalDecimalFraction
:::
TemporalDecimalSeparator
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
::: one of .
,
21.4.1.33.1 IsTimeZoneOffsetString ( offsetString
)
抽象操作 IsTimeZoneOffsetString 接受参数 offsetString (一个
String)并返回一个 Boolean。返回值指示
offsetString 是否符合 UTCOffset 给出的语法。它在被调用时执行以下步骤:
设 parseResult 为 ParseText (offsetString ,
UTCOffset )。
如果 parseResult 是一个错误的列表 ,返回
false 。
返回 true 。
21.4.1.33.2 ParseTimeZoneOffsetString (
offsetString )
抽象操作 ParseTimeZoneOffsetString 接受参数 offsetString
(一个 String)并返回一个整数 。返回值是对应于字符串 offsetString 的 UTC
偏移,以纳秒为单位。它在被调用时执行以下步骤:
设 parseResult 为 ParseText (offsetString ,
UTCOffset )。
断言 :parseResult 不是一个错误的列表 。
断言 :parseResult 包含一个
ASCIISign
解析节点 。
设 parsedSign 为 parseResult 中包含的 ASCIISign 解析节点 匹配的源文本 。
如果 parsedSign 是单个代码点 U+002D(连字符减号),那么
设 sign 为 -1。
否则,
设 sign 为 1。
注意:下面 StringToNumber
的应用不会丢失精度,因为每个解析值都保证是一个足够短的十进制数字字符串。
断言 :parseResult 包含一个
Hour 解析节点 。
设 parsedHours 为 parseResult 中包含的 Hour 解析节点 匹配的源文本 。
设 hours 为 ℝ (StringToNumber (CodePointsToString (parsedHours )))。
如果 parseResult 不包含 MinuteSecond 解析节点 ,那么
设 minutes 为 0。
否则,
设 parsedMinutes 为 parseResult 中包含的第一个 MinuteSecond 解析节点 匹配的源文本 。
设 minutes 为 ℝ (StringToNumber (CodePointsToString (parsedMinutes )))。
如果 parseResult 不包含两个 MinuteSecond 解析节点 ,那么
设 seconds 为 0。
否则,
设 parsedSeconds 为 parseResult 中包含的第二个 MinuteSecond 解析节点 匹配的源文本 。
设 seconds 为 ℝ (StringToNumber (CodePointsToString (parsedSeconds )))。
如果 parseResult 不包含 TemporalDecimalFraction
解析节点 ,那么
设 nanoseconds 为 0。
否则,
设 parsedFraction 为 parseResult 中包含的 TemporalDecimalFraction
解析节点 匹配的源文本 。
设 fraction 为 CodePointsToString (parsedFraction )
和 "000000000" 的字符串连接 。
设 nanosecondsString 为 fraction 从 1 到 10 的子字符串 。
设 nanoseconds 为 ℝ (StringToNumber (nanosecondsString ))。
返回 sign × (((hours × 60 + minutes ) × 60 +
seconds ) × 109 + nanoseconds )。
21.4.2 Date 构造函数
Date 构造函数 :
是 %Date% 。
是 "Date" 属性在 全局对象 上的初始值。
作为 构造函数
调用时,创建并初始化一个新的 Date。
作为函数而非 构造函数 调用时,返回一个表示当前时间(UTC)的字符串。
是一个其行为根据参数数量和类型而不同的函数。
可作为类定义中 extends 子句的值使用。打算继承指定 Date 行为的子类 构造函数 必须包含对 Date 构造函数 的
super 调用,以使用 [[DateValue]] 内部槽创建并初始化子类实例。
21.4.2.1 Date ( ...values )
当调用此函数时,将执行以下步骤:
如果 NewTarget 为 undefined ,则
令 now 为标识当前时间的 时间值 (UTC)。
返回 ToDateString (now )。
令 numberOfArgs 为 values 中元素的数量。
如果 numberOfArgs = 0,则
令 dv 为标识当前时间的 时间值 (UTC)。
否则如果 numberOfArgs = 1,则
令 value 为 values [0]。
如果 value 是一个对象 且 value 具有
[[DateValue]] 内部槽,则
令 tv 为 value .[[DateValue]] 。
否则,
令 v 为 ? ToPrimitive (value )。
如果 v 是字符串 ,则
断言 :下一步永远不会返回 非正常完成 ,因为
v
是字符串 。
令 tv 为以与 parse 方法 (21.4.3.2 )
完全相同的方式解析 v 作为日期的结果。
否则,
令 tv 为 ? ToNumber (v )。
令 dv 为 TimeClip (tv )。
否则,
断言 :numberOfArgs ≥ 2。
令 y 为 ? ToNumber (values [0])。
令 m 为 ? ToNumber (values [1])。
如果 numberOfArgs > 2,令 dt 为 ? ToNumber (values [2]);否则令
dt 为 1 𝔽 。
如果 numberOfArgs > 3,令 h 为 ? ToNumber (values [3]);否则令
h 为 +0 𝔽 。
如果 numberOfArgs > 4,令 min 为 ? ToNumber (values [4]);否则令
min 为 +0 𝔽 。
如果 numberOfArgs > 5,令 s 为 ? ToNumber (values [5]);否则令
s 为 +0 𝔽 。
如果 numberOfArgs > 6,令 milli 为 ? ToNumber (values [6]);否则令
milli 为 +0 𝔽 。
令 yr 为 MakeFullYear (y )。
令 finalDate 为 MakeDate (MakeDay (yr ,
m , dt ), MakeTime (h ,
min , s , milli ))。
令 dv 为 TimeClip (UTC (finalDate ))。
令 O 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%Date.prototype%" , « [[DateValue]] »)。
设置 O .[[DateValue]] 为 dv 。
返回 O 。
21.4.3 Date 构造函数的属性
Date 构造函数 :
21.4.3.1 Date.now ( )
此函数返回表示调用时 UTC 日期和时间的 时间值 。
21.4.3.2 Date.parse ( string )
此函数对其参数应用 ToString 运算符。如果 ToString 产生 非正常完成 ,则会立即返回该
Completion
Record 。否则,此函数将结果字符串作为日期和时间进行解释;返回一个 Number,即与该日期和时间对应的 UTC 时间值 。字符串可能会被解释为本地时间、UTC
时间或其他时区的时间,具体取决于字符串的内容。函数首先尝试按照日期时间字符串格式 (21.4.1.32 ),包括扩展年份,解析该字符串。如果字符串不符合该格式,函数可以退回到实现相关的启发式算法或实现相关的日期格式。无法识别或包含越界格式元素值的字符串会导致该函数返回
NaN 。
如果字符串符合 日期时间字符串格式 ,则缺失的格式元素将用替代值补齐。当
MM 或 DD 元素缺失时,使用 "01" 。当
HH、mm 或 ss 元素缺失时,使用 "00" 。当
sss 元素缺失时,使用 "000" 。当缺少 UTC 偏移表示时,仅日期形式被解释为 UTC
时间,日期-时间形式被解释为本地时间。
如果 x 是 ECMAScript 某一实现中毫秒数为零的 Date,则在该实现中,以下所有表达式(如果所有相关属性都是初始值)应产生相同的数值:
x.valueOf ()
Date .parse (x.toString ())
Date .parse (x.toUTCString ())
Date .parse (x.toISOString ())
然而,下面的表达式
Date .parse (x.toLocaleString ())
不要求产生与前三个表达式相同的数值,并且通常当传入的字符串不符合日期时间字符串格式 (21.4.1.32 ),且无法由
toString 或 toUTCString 方法在该实现中产生时,该函数的返回值是 实现定义 的。
21.4.3.3 Date.prototype
Date.prototype 的初始值是 Date 原型对象 。
该属性具有属性 { [[Writable]] : false , [[Enumerable]] : false ,
[[Configurable]] : false }。
21.4.3.4 Date.UTC ( year [ , month [ ,
date [ , hours [ , minutes [ , seconds [ ,
ms ] ] ] ] ] ] )
当调用此函数时,将执行以下步骤:
令 y 为 ? ToNumber (year )。
如果 month 存在,令 m 为 ? ToNumber (month );否则,令
m 为 +0 𝔽 。
如果 date 存在,令 dt 为 ? ToNumber (date );否则,令
dt 为 1 𝔽 。
如果 hours 存在,令 h 为 ? ToNumber (hours );否则,令
h 为 +0 𝔽 。
如果 minutes 存在,令 min 为 ? ToNumber (minutes );否则,令
min 为 +0 𝔽 。
如果 seconds 存在,令 s 为 ? ToNumber (seconds );否则,令
s 为 +0 𝔽 。
如果 ms 存在,令 milli 为 ? ToNumber (ms );否则,令
milli 为 +0 𝔽 。
令 yr 为 MakeFullYear (y )。
返回 TimeClip (MakeDate (MakeDay (yr , m ,
dt ), MakeTime (h , min ,
s , milli )))。
该函数的 "length" 属性值为 7 𝔽 。
注意
此函数与 Date 构造函数 有两点不同:它返回一个 Number 形式的 时间值 ,而不是创建一个
Date,并且参数被解释为 UTC,而不是本地时间。
21.4.4 Date 原型对象的属性
Date 原型对象 :
是 %Date.prototype% 。
它本身是一个 普通对象 。
不是 Date 实例,也没有 [[DateValue]] 内部槽。
具有 [[Prototype]] 内部槽,其值为 %Object.prototype% 。
除非另有明确规定,下文定义的 Date 原型对象的方法不是泛型的,传递给它们的 this 值必须是一个已经初始化了 [[DateValue]] 内部槽,并且该槽为一个 时间值 的对象。
21.4.4.1 Date.prototype.constructor
Date.prototype.constructor 的初始值是 %Date% 。
21.4.4.2 Date.prototype.getDate ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 DateFromTime (LocalTime (t ))。
21.4.4.3 Date.prototype.getDay ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 WeekDay (LocalTime (t ))。
21.4.4.4 Date.prototype.getFullYear ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 YearFromTime (LocalTime (t ))。
21.4.4.5 Date.prototype.getHours ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 HourFromTime (LocalTime (t ))。
21.4.4.6 Date.prototype.getMilliseconds ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 msFromTime (LocalTime (t ))。
21.4.4.7 Date.prototype.getMinutes ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 MinFromTime (LocalTime (t ))。
21.4.4.8 Date.prototype.getMonth ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 MonthFromTime (LocalTime (t ))。
21.4.4.9 Date.prototype.getSeconds ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 SecFromTime (LocalTime (t ))。
21.4.4.10 Date.prototype.getTime ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
返回 dateObject .[[DateValue]] 。
21.4.4.11 Date.prototype.getTimezoneOffset ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 (t - LocalTime (t )) / msPerMinute 。
21.4.4.12 Date.prototype.getUTCDate ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 DateFromTime (t )。
21.4.4.13 Date.prototype.getUTCDay ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 WeekDay (t )。
21.4.4.14 Date.prototype.getUTCFullYear ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 YearFromTime (t )。
21.4.4.15 Date.prototype.getUTCHours ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 HourFromTime (t )。
21.4.4.16 Date.prototype.getUTCMilliseconds ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 msFromTime (t )。
21.4.4.17 Date.prototype.getUTCMinutes ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 MinFromTime (t )。
21.4.4.18 Date.prototype.getUTCMonth ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 MonthFromTime (t )。
21.4.4.19 Date.prototype.getUTCSeconds ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则返回 NaN 。
返回 SecFromTime (t )。
21.4.4.20 Date.prototype.setDate ( date )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 dt 为 ? ToNumber (date )。
如果 t 为 NaN ,则返回 NaN 。
设置 t 为 LocalTime (t )。
令 newDate 为 MakeDate (MakeDay (YearFromTime (t ),
MonthFromTime (t ),
dt ), TimeWithinDay (t ))。
令 u 为 TimeClip (UTC (newDate ))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
21.4.4.21 Date.prototype.setFullYear ( year [ ,
month [ , date ] ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 y 为 ? ToNumber (year )。
如果 t 为 NaN ,则设置 t 为
+0 𝔽 ;否则,设置 t 为 LocalTime (t )。
如果 month 未给出,令 m 为 MonthFromTime (t );否则,令
m 为 ? ToNumber (month )。
如果 date 未给出,令 dt 为 DateFromTime (t );否则,令
dt 为 ? ToNumber (date )。
令 newDate 为 MakeDate (MakeDay (y ,
m , dt ), TimeWithinDay (t ))。
令 u 为 TimeClip (UTC (newDate ))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
该方法的 "length" 属性值为 3 𝔽 。
注意
如果未给出 month ,本方法表现为 month 的值为 getMonth()。如果未给出
date ,则表现为 date 的值为 getDate()。
21.4.4.22 Date.prototype.setHours ( hour [ ,
min [ , sec [ , ms ] ] ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 h 为 ? ToNumber (hour )。
如果 min 给出,令 m 为 ? ToNumber (min )。
如果 sec 给出,令 s 为 ? ToNumber (sec )。
如果 ms 给出,令 milli 为 ? ToNumber (ms )。
如果 t 为 NaN ,则返回 NaN 。
设置 t 为 LocalTime (t )。
如果 min 未给出,令 m 为 MinFromTime (t )。
如果 sec 未给出,令 s 为 SecFromTime (t )。
如果 ms 未给出,令 milli 为 msFromTime (t )。
令 date 为 MakeDate (Day (t ), MakeTime (h , m ,
s , milli ))。
令 u 为 TimeClip (UTC (date ))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
该方法的 "length" 属性值为 4 𝔽 。
注意
如果未给出 min ,本方法表现为 min 的值为 getMinutes()。如果未给出
sec ,则表现为 sec 的值为 getSeconds()。如果未给出
ms ,则表现为 ms 的值为 getMilliseconds()。
21.4.4.23 Date.prototype.setMilliseconds ( ms )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
将 ms 设为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
将 t 设为 LocalTime (t )。
令 time 为 MakeTime (HourFromTime (t ),
MinFromTime (t ), SecFromTime (t ),
ms )。
令 u 为 TimeClip (UTC (MakeDate (Day (t ),
time )))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
21.4.4.24 Date.prototype.setMinutes ( min [ ,
sec [ , ms ] ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 m 为 ? ToNumber (min )。
如果 sec 给出,令 s 为 ? ToNumber (sec )。
如果 ms 给出,令 milli 为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
设置 t 为 LocalTime (t )。
如果 sec 未给出,令 s 为 SecFromTime (t )。
如果 ms 未给出,令 milli 为 msFromTime (t )。
令 date 为 MakeDate (Day (t ), MakeTime (HourFromTime (t ),
m , s , milli ))。
令 u 为 TimeClip (UTC (date ))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
该方法的 "length" 属性值为 3 𝔽 。
注意
如果未给出 sec ,本方法表现为 sec 的值为 getSeconds()。如果未给出
ms ,则表现为 ms 的值为 getMilliseconds()。
21.4.4.25 Date.prototype.setMonth ( month [ ,
date ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 m 为 ? ToNumber (month )。
如果 date 给出,令 dt 为 ? ToNumber (date )。
如果 t 为 NaN ,返回 NaN 。
设置 t 为 LocalTime (t )。
如果 date 未给出,令 dt 为 DateFromTime (t )。
令 newDate 为 MakeDate (MakeDay (YearFromTime (t ),
m , dt ), TimeWithinDay (t ))。
令 u 为 TimeClip (UTC (newDate ))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
该方法的 "length" 属性值为 2 𝔽 。
注意
如果未给出 date ,本方法表现为 date 的值为 getDate()。
21.4.4.26 Date.prototype.setSeconds ( sec [ ,
ms ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 s 为 ? ToNumber (sec )。
如果 ms 给出,令 milli 为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
设置 t 为 LocalTime (t )。
如果 ms 未给出,令 milli 为 msFromTime (t )。
令 date 为 MakeDate (Day (t ), MakeTime (HourFromTime (t ),
MinFromTime (t ),
s , milli ))。
令 u 为 TimeClip (UTC (date ))。
设置 dateObject .[[DateValue]] 为 u 。
返回 u 。
该方法的 "length" 属性值为 2 𝔽 。
注意
如果未给出 ms ,本方法表现为 ms 的值为 getMilliseconds()。
21.4.4.27 Date.prototype.setTime ( time )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 ? ToNumber (time )。
令 v 为 TimeClip (t )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
21.4.4.28 Date.prototype.setUTCDate ( date )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 dt 为 ? ToNumber (date )。
如果 t 为 NaN ,返回 NaN 。
令 newDate 为 MakeDate (MakeDay (YearFromTime (t ),
MonthFromTime (t ),
dt ), TimeWithinDay (t ))。
令 v 为 TimeClip (newDate )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
21.4.4.29 Date.prototype.setUTCFullYear ( year [ ,
month [ , date ] ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
如果 t 为 NaN ,则设置 t 为
+0 𝔽 。
令 y 为 ? ToNumber (year )。
如果 month 未给出,令 m 为 MonthFromTime (t );
否则,令 m 为 ? ToNumber (month )。
如果 date 未给出,令 dt 为 DateFromTime (t );
否则,令 dt 为 ? ToNumber (date )。
令 newDate 为 MakeDate (MakeDay (y ,
m , dt ), TimeWithinDay (t ))。
令 v 为 TimeClip (newDate )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
该方法的 "length" 属性值为 3 𝔽 。
注意
如果未给出 month ,本方法表现为 month 的值为 getUTCMonth()。如果未给出
date ,则表现为 date 的值为 getUTCDate()。
21.4.4.30 Date.prototype.setUTCHours ( hour [ ,
min [ , sec [ , ms ] ] ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 h 为 ? ToNumber (hour )。
如果 min 给出,令 m 为 ? ToNumber (min )。
如果 sec 给出,令 s 为 ? ToNumber (sec )。
如果 ms 给出,令 milli 为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
如果 min 未给出,令 m 为 MinFromTime (t )。
如果 sec 未给出,令 s 为 SecFromTime (t )。
如果 ms 未给出,令 milli 为 msFromTime (t )。
令 date 为 MakeDate (Day (t ), MakeTime (h , m ,
s , milli ))。
令 v 为 TimeClip (date )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
该方法的 "length" 属性值为 4 𝔽 。
注意
如果未给出 min ,本方法表现为 min 的值为 getUTCMinutes()。如果未给出
sec ,则表现为 sec 的值为 getUTCSeconds()。如果未给出
ms ,则表现为 ms 的值为 getUTCMilliseconds()。
21.4.4.31 Date.prototype.setUTCMilliseconds ( ms )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
将 ms 设为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
令 time 为 MakeTime (HourFromTime (t ),
MinFromTime (t ), SecFromTime (t ),
ms )。
令 v 为 TimeClip (MakeDate (Day (t ),
time ))。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
21.4.4.32 Date.prototype.setUTCMinutes ( min [ ,
sec [ , ms ] ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 m 为 ? ToNumber (min )。
如果 sec 给出,令 s 为 ? ToNumber (sec )。
如果 ms 给出,令 milli 为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
如果 sec 未给出,令 s 为 SecFromTime (t )。
如果 ms 未给出,令 milli 为 msFromTime (t )。
令 date 为 MakeDate (Day (t ), MakeTime (HourFromTime (t ),
m , s , milli ))。
令 v 为 TimeClip (date )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
该方法的 "length" 属性值为 3 𝔽 。
注意
如果未给出 sec ,本方法表现为 sec 的值为 getUTCSeconds()。如果未给出
ms ,则表现为 ms 的值为 getUTCMilliseconds()。
21.4.4.33 Date.prototype.setUTCMonth ( month [ ,
date ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 m 为 ? ToNumber (month )。
如果 date 给出,令 dt 为 ? ToNumber (date )。
如果 t 为 NaN ,返回 NaN 。
如果 date 未给出,令 dt 为 DateFromTime (t )。
令 newDate 为 MakeDate (MakeDay (YearFromTime (t ),
m , dt ), TimeWithinDay (t ))。
令 v 为 TimeClip (newDate )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
该方法的 "length" 属性值为 2 𝔽 。
注意
如果未给出 date ,本方法表现为 date 的值为 getUTCDate()。
21.4.4.34 Date.prototype.setUTCSeconds ( sec [ ,
ms ] )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 t 为 dateObject .[[DateValue]] 。
令 s 为 ? ToNumber (sec )。
如果 ms 给出,令 milli 为 ? ToNumber (ms )。
如果 t 为 NaN ,返回 NaN 。
如果 ms 未给出,令 milli 为 msFromTime (t )。
令 date 为 MakeDate (Day (t ), MakeTime (HourFromTime (t ),
MinFromTime (t ),
s , milli ))。
令 v 为 TimeClip (date )。
设置 dateObject .[[DateValue]] 为 v 。
返回 v 。
该方法的 "length" 属性值为 2 𝔽 。
注意
如果未给出 ms ,本方法表现为 ms 的值为 getUTCMilliseconds()。
21.4.4.35 Date.prototype.toDateString ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 tv 为 dateObject .[[DateValue]] 。
如果 tv 为 NaN ,返回 "Invalid
Date" 。
令 t 为 LocalTime (tv )。
返回 DateString (t )。
21.4.4.36 Date.prototype.toISOString ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 tv 为 dateObject .[[DateValue]] 。
如果 tv 为 NaN ,抛出 RangeError 异常。
断言 :tv 是一个 整数
Number 。
如果 tv 所对应的年份不能用 日期时间字符串格式
表示,则抛出 RangeError 异常。
返回 tv 在 UTC 时标下、日期时间字符串格式
的字符串表示,包括所有格式元素及 UTC 偏移 "Z"。
21.4.4.37 Date.prototype.toJSON ( key )
此方法为 JSON.stringify (25.5.2 ) 提供 Date 的字符串表示。
调用该方法时,执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 tv 为 ? ToPrimitive (O ,
number )。
如果 tv 是
Number 且 tv 不是 有限值 ,则返回
null 。
返回 ? Invoke (O ,
"toISOString" )。
注意 1
注意 2
此方法有意设计为泛型;它不要求其 this 值为 Date。因此,可以转移到其他类型的对象上作为方法使用。但该对象必须有
toISOString 方法。
21.4.4.38 Date.prototype.toLocaleDateString ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现未包含 ECMA-402
API,则使用以下规范:
该方法返回一个字符串值。字符串内容是实现定义 的,但旨在以方便且易于理解的形式,表示当前时区下 Date
的“日期”部分,符合宿主环境 当前区域设置的习惯。
本方法的可选参数含义在 ECMA-402 规范中定义;未包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
21.4.4.39 Date.prototype.toLocaleString ( [ reserved1
[ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现未包含 ECMA-402
API,则使用以下规范:
该方法返回一个字符串值。字符串内容是实现定义 的,但旨在以方便且易于理解的形式,表示当前时区下的
Date,符合宿主环境 当前区域设置的习惯。
本方法的可选参数含义在 ECMA-402 规范中定义;未包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
21.4.4.40 Date.prototype.toLocaleTimeString ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现未包含 ECMA-402
API,则使用以下规范:
该方法返回一个字符串值。字符串内容是实现定义 的,但旨在以方便且易于理解的形式,表示当前时区下 Date
的“时间”部分,符合宿主环境 当前区域设置的习惯。
本方法的可选参数含义在 ECMA-402 规范中定义;未包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
21.4.4.41 Date.prototype.toString ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 tv 为 dateObject .[[DateValue]] 。
返回 ToDateString (tv )。
注意 1
对于任何 Date d,如果 d.[[DateValue]] 能被
1000 整除,则 Date.parse(d.toString()) 的结果等于
d.valueOf()。参见21.4.3.2 。
注意 2
此方法不是泛型;如果其 this 值不是 Date,则会抛出 TypeError
异常。因此,不能转移到其他类型的对象用作方法。
21.4.4.41.1 TimeString ( tv )
抽象操作 TimeString 接受参数 tv (Number,但不是 NaN ),返回一个字符串。调用时执行以下步骤:
令 hour 为 ToZeroPaddedDecimalString (ℝ (HourFromTime (tv )),
2)。
令 minute 为 ToZeroPaddedDecimalString (ℝ (MinFromTime (tv )), 2)。
令 second 为 ToZeroPaddedDecimalString (ℝ (SecFromTime (tv )), 2)。
返回 字符串拼接
hour 、":" 、minute 、":" 、second 、0x0020(空格)、"GMT" 。
21.4.4.41.2 DateString ( tv )
抽象操作 DateString 接受参数 tv (Number,但不是 NaN ),返回一个字符串。调用时执行以下步骤:
令 weekday 为 表 65 中编号为
WeekDay (tv ) 的 Name。
令 month 为 表 66
中编号为 MonthFromTime (tv ) 的
Name。
令 day 为 ToZeroPaddedDecimalString (ℝ (DateFromTime (tv )),
2)。
令 yv 为 YearFromTime (tv )。
如果 yv 是 +0 𝔽 或 yv >
+0 𝔽 ,则 yearSign 为空字符串;否则
yearSign 为 "-" 。
令 paddedYear 为 ToZeroPaddedDecimalString (abs (ℝ (yv )), 4)。
返回 字符串拼接
weekday 、0x0020(空格)、month 、0x0020、day 、0x0020、yearSign
和 paddedYear 。
表 65:一周中各天的名称
编号
名称
+0 𝔽
"Sun"
1 𝔽
"Mon"
2 𝔽
"Tue"
3 𝔽
"Wed"
4 𝔽
"Thu"
5 𝔽
"Fri"
6 𝔽
"Sat"
表 66:一年中各月的名称
编号
名称
+0 𝔽
"Jan"
1 𝔽
"Feb"
2 𝔽
"Mar"
3 𝔽
"Apr"
4 𝔽
"May"
5 𝔽
"Jun"
6 𝔽
"Jul"
7 𝔽
"Aug"
8 𝔽
"Sep"
9 𝔽
"Oct"
10 𝔽
"Nov"
11 𝔽
"Dec"
21.4.4.41.3 TimeZoneString ( tv )
抽象操作 TimeZoneString 接受参数 tv (整数
Number ),返回一个字符串。调用时执行以下步骤:
令 systemTimeZoneIdentifier 为 SystemTimeZoneIdentifier ()。
如果 IsTimeZoneOffsetString (systemTimeZoneIdentifier )
为 true ,则
令 offsetNs 为 ParseTimeZoneOffsetString (systemTimeZoneIdentifier )。
否则,
令 offsetNs 为 GetNamedTimeZoneOffsetNanoseconds (systemTimeZoneIdentifier ,
ℤ (ℝ (tv ) × 106 ))。
令 offset 为 𝔽 (truncate (offsetNs /
106 ))。
如果 offset 为 +0 𝔽 或 offset
> +0 𝔽 ,则
令 offsetSign 为 "+" 。
令 absOffset 为 offset 。
否则,
令 offsetSign 为 "-" 。
令 absOffset 为 -offset 。
令 offsetMin 为 ToZeroPaddedDecimalString (ℝ (MinFromTime (absOffset )),
2)。
令 offsetHour 为 ToZeroPaddedDecimalString (ℝ (HourFromTime (absOffset )),
2)。
令 tzName 为一个实现定义 的字符串,其值可以为空字符串,也可以是
0x0020(空格)、0x0028(左括号)、实现定义 的时区名称和
0x0029(右括号)的字符串拼接。
返回 字符串拼接
offsetSign 、offsetHour 、offsetMin 和
tzName 。
21.4.4.41.4 ToDateString ( tv )
抽象操作 ToDateString 接受参数 tv (整数 Number 或
NaN ),返回一个字符串。调用时执行以下步骤:
如果 tv 为 NaN ,返回 "Invalid Date" 。
令 t 为 LocalTime (tv )。
返回 字符串拼接 DateString (t )、0x0020(空格)、TimeString (t ) 和
TimeZoneString (tv )。
21.4.4.42 Date.prototype.toTimeString ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 tv 为 dateObject .[[DateValue]] 。
如果 tv 为 NaN ,返回 "Invalid Date" 。
令 t 为 LocalTime (tv )。
返回 字符串拼接 TimeString (t ) 和 TimeZoneString (tv )。
21.4.4.43 Date.prototype.toUTCString ( )
该方法返回一个字符串值,表示与 this 值对应的时间点。字符串格式基于 RFC 7231 的 "HTTP-date",并推广以支持
ECMAScript Dates 支持的完整时间范围。
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
令 tv 为 dateObject .[[DateValue]] 。
如果 tv 为 NaN ,返回 "Invalid Date" 。
令 weekday 为 表 65 中编号为 WeekDay (tv ) 的 Name。
令 month 为 表 66 中编号为 MonthFromTime (tv ) 的
Name。
令 day 为 ToZeroPaddedDecimalString (ℝ (DateFromTime (tv )), 2)。
令 yv 为 YearFromTime (tv )。
如果 yv 是 +0 𝔽 或 yv >
+0 𝔽 ,则 yearSign 为空字符串;否则
yearSign 为 "-" 。
令 paddedYear 为 ToZeroPaddedDecimalString (abs (ℝ (yv )), 4)。
返回 字符串拼接
weekday 、"," 、0x0020(空格)、day 、0x0020、month 、0x0020、yearSign 、paddedYear 、0x0020
和 TimeString (tv )。
21.4.4.44 Date.prototype.valueOf ( )
调用该方法时,执行以下步骤:
令 dateObject 为 this 值。
执行 ? RequireInternalSlot (dateObject ,
[[DateValue]] )。
返回 dateObject .[[DateValue]] 。
21.4.4.45 Date.prototype [ %Symbol.toPrimitive% ] (
hint )
此方法被 ECMAScript 语言运算符调用,用于将 Date 转换为原始值。hint 的允许值为
"default" 、"number" 和 "string" 。Date
是内置 ECMAScript 对象中唯一将 "default" 视为等价于 "string"
的对象。所有其他内置 ECMAScript 对象都将 "default" 视为等价于 "number" 。
调用该方法时,执行以下步骤:
令 O 为 this 值。
如果 O 不是对象 ,则抛出 TypeError
异常。
如果 hint 是 "string" 或 "default" ,则
令 tryFirst 为 string 。
否则如果 hint 是 "number" ,则
令 tryFirst 为 number 。
否则,
抛出 TypeError 异常。
返回 ? OrdinaryToPrimitive (O ,
tryFirst )。
该属性具有属性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true }。
本方法的 "name" 属性值为 "[Symbol.toPrimitive]" 。
21.4.5 Date 实例的属性
Date 实例是普通对象 ,继承自Date 原型对象 的属性。Date
实例还拥有一个 [[DateValue]] 内部槽。[[DateValue]] 内部槽即该
Date 实例所表示的时间值 。
22 文本处理
22.1 字符串对象
22.1.1 String 构造函数
String 构造函数 :
是 %String% 。
是 "String" 属性在 全局对象 上的初始值。
作为 构造函数
调用时,创建并初始化一个新的 String 对象。
作为函数调用而非 构造函数 时,执行类型转换。
可作为类定义中 extends 子句的值使用。打算继承指定 String 行为的子类 构造函数 必须包含对 String 构造函数 的
super 调用,以用 [[StringData]] 内部槽创建并初始化子类实例。
22.1.1.1 String ( value )
当调用该函数时,执行以下步骤:
如果 value 未给出,则
令 s 为空字符串。
否则,
如果 NewTarget 为 undefined 且 value 是
Symbol ,则返回 SymbolDescriptiveString (value )。
令 s 为 ? ToString (value )。
如果 NewTarget 为 undefined ,返回 s 。
返回 StringCreate (s ,
? GetPrototypeFromConstructor (NewTarget,
"%String.prototype%" ))。
22.1.2 String 构造函数的属性
String 构造函数 :
22.1.2.1 String.fromCharCode ( ...codeUnits )
该函数可以接收任意数量的参数,这些参数形成余参数 codeUnits 。
调用该函数时,执行以下步骤:
令 result 为空字符串。
对于 codeUnits 中的每个元素 next ,执行
令 nextCU 为数值为 ℝ (? ToUint16 (next )) 的码元。
将 result 设为 字符串拼接
result 和 nextCU 的结果。
返回 result 。
该函数的 "length" 属性值为 1 𝔽 。
22.1.2.2 String.fromCodePoint ( ...codePoints )
该函数可以接收任意数量的参数,这些参数形成余参数 codePoints 。
调用该函数时,执行以下步骤:
令 result 为空字符串。
对于 codePoints 中的每个元素 next ,执行
令 nextCP 为 ? ToNumber (next )。
如果 nextCP 不是 整数 Number ,抛出
RangeError 异常。
如果 ℝ (nextCP ) < 0 或 ℝ (nextCP ) > 0x10FFFF,抛出
RangeError 异常。
将 result 设为 字符串拼接
result 和 UTF16EncodeCodePoint (ℝ (nextCP )) 的结果。
断言 :如果
codePoints 为空,则 result 为空字符串。
返回 result 。
该函数的 "length" 属性值为 1 𝔽 。
22.1.2.3 String.prototype
String.prototype 的初始值为 String 原型对象 。
该属性具有属性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false }。
22.1.2.4 String.raw ( template ,
...substitutions )
该函数可以接收可变数量的参数。第一个参数为 template ,其余参数组成 List
substitutions 。
调用该函数时,执行以下步骤:
令 substitutionCount 为 substitutions 的元素个数。
令 cooked 为 ? ToObject (template )。
令 literals 为 ? ToObject (? Get (cooked ,
"raw" ))。
令 literalCount 为 ? LengthOfArrayLike (literals )。
如果 literalCount ≤ 0,返回空字符串。
令 R 为空字符串。
令 nextIndex 为 0。
重复,
令 nextLiteralVal 为 ? Get (literals ,
! ToString (𝔽 (nextIndex )))。
令 nextLiteral 为 ? ToString (nextLiteralVal )。
将 R 设为 字符串拼接 R 和
nextLiteral 的结果。
如果 nextIndex + 1 = literalCount ,返回 R 。
如果 nextIndex < substitutionCount ,则
令 nextSubVal 为
substitutions [nextIndex ]。
令 nextSub 为 ? ToString (nextSubVal )。
将 R 设为 字符串拼接
R 和 nextSub 的结果。
将 nextIndex 设为 nextIndex + 1。
注意
该函数用于作为标记模板(Tagged Template)(13.3.11 )的标记函数使用。当以此方式调用时,第一个参数将是格式良好的模板对象,其余参数是替换值。
22.1.3 String 原型对象的属性
String 原型对象 :
是 %String.prototype% 。
是 String
特殊对象 ,并拥有为此类对象规定的内部方法。
有一个 [[StringData]] 内部槽,其值为空字符串。
有一个 "length" 属性,其初始值为 +0 𝔽 ,属性为 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false }。
有一个 [[Prototype]] 内部槽,其值为 %Object.prototype% 。
除非另有明确声明,下文定义的 String 原型对象的方法都不是泛型方法,传递给它们的 this 值必须是 String 值或具有已初始化为 String
值的 [[StringData]] 内部槽的对象。
22.1.3.1 String.prototype.at ( index )
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 len 为 S 的长度。
令 relativeIndex 为 ? ToIntegerOrInfinity (index )。
如果 relativeIndex ≥ 0,则
令 k 为 relativeIndex 。
否则,
令 k 为 len + relativeIndex 。
如果 k < 0 或 k ≥ len ,返回
undefined 。
返回 substring S 从 k 到
k + 1。
22.1.3.2 String.prototype.charAt ( pos )
注 1
此方法返回包含在将此对象转换为 String 后的字符串中索引为 pos
的码元的单元素字符串。如果该索引处没有元素,则返回空字符串。结果是
String 值,而不是 String 对象。
如果 pos 是 整数 Number ,则
x.charAt(pos) 的结果等价于 x.substring(pos, pos + 1)。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 position 为 ? ToIntegerOrInfinity (pos )。
令 size 为 S 的长度。
如果 position < 0 或 position ≥ size ,返回空字符串。
返回 substring S 从
position 到 position + 1。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.3 String.prototype.charCodeAt ( pos )
注 1
此方法返回一个 Number(一个非负的整数 Number ,小于
216 ),表示将此对象转换为 String 后字符串中索引为 pos 处的码元的数值。如果该索引处没有元素,则结果为
NaN 。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 position 为 ? ToIntegerOrInfinity (pos )。
令 size 为 S 的长度。
如果 position < 0 或 position ≥ size ,返回
NaN 。
返回 Number value for 字符串 S
中索引为 position 的码元的数值。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.4 String.prototype.codePointAt ( pos )
注 1
此方法返回一个非负的整数 Number ,小于等于
0x10FFFF 𝔽 ,表示在将该对象转换为 String 后字符串中索引为 pos
处开始的 UTF-16 编码码点(6.1.4 )的数值。如果该索引处没有元素,则结果为
undefined 。如果 pos 处不是有效的 UTF-16 代理对 的开始,则结果为 pos 处的码元。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 position 为 ? ToIntegerOrInfinity (pos )。
令 size 为 S 的长度。
如果 position < 0 或 position ≥ size ,返回
undefined 。
令 cp 为 CodePointAt (S ,
position )。
返回 𝔽 (cp .[[CodePoint]] )。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.5 String.prototype.concat ( ...args )
注 1
调用此方法时,返回由 this 值(转换为 String)码元后跟每个参数转换为 String 后的码元组成的 String
值。结果是
String 值,而不是 String 对象。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 R 为 S 。
对于 args 中的每个元素 next ,执行
令 nextString 为 ? ToString (next )。
将 R 设为 字符串拼接 R 和
nextString 的结果。
返回 R 。
该方法的 "length" 属性值为 1 𝔽 。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.6 String.prototype.constructor
String.prototype.constructor 的初始值为 %String% 。
22.1.3.7 String.prototype.endsWith ( searchString [ ,
endPosition ] )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 isRegExp 为 ? IsRegExp (searchString )。
如果 isRegExp 为 true ,抛出 TypeError 异常。
令 searchStr 为 ? ToString (searchString )。
令 len 为 S 的长度。
如果 endPosition 为 undefined ,令 pos 为
len ;否则令 pos 为 ? ToIntegerOrInfinity (endPosition )。
令 end 为 clamping pos 介于 0 和
len 之间的结果。
令 searchLength 为 searchStr 的长度。
如果 searchLength = 0,返回 true 。
令 start 为 end - searchLength 。
如果 start < 0,返回 false 。
令 substring 为 substring S 从 start 到
end 。
如果 substring 等于 searchStr ,返回 true 。
返回 false 。
注 1
如果 searchString (转换为 String)码元序列与本对象(转换为 String)中从 endPosition -
length(this) 开始的对应码元相同,则该方法返回 true ,否则返回 false 。
注 2
如果第一个参数是 RegExp 抛出异常,是为了允许后续标准版本定义支持此类参数值的扩展。
注 3
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.8 String.prototype.includes ( searchString [ ,
position ] )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 isRegExp 为 ? IsRegExp (searchString )。
如果 isRegExp 为 true ,抛出 TypeError 异常。
令 searchStr 为 ? ToString (searchString )。
令 pos 为 ? ToIntegerOrInfinity (position )。
断言 :如果
position 为 undefined ,则 pos 为 0。
令 len 为 S 的长度。
令 start 为 clamping pos 介于 0 和
len 之间的结果。
令 index 为 StringIndexOf (S ,
searchStr , start )。
如果 index 为 not-found ,返回 false 。
返回 true 。
注 1
如果 searchString 作为子串 出现在将此对象转换为 String
后的结果中,且索引大于等于 position ,则该函数返回 true ;否则返回
false 。如果 position 为 undefined ,则默认值为
0,因此会搜索整个字符串。
注 2
如果第一个参数是 RegExp 抛出异常,是为了允许后续标准版本定义支持此类参数值的扩展。
注 3
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.9 String.prototype.indexOf ( searchString [ ,
position ] )
注 1
如果 searchString 作为子串 出现在将此对象转换为 String
后的结果中,且索引大于等于 position ,则返回最小的此类索引,否则返回
-1 𝔽 。如果 position 为
undefined ,则假定为 +0 𝔽 ,即搜索整个字符串。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 searchStr 为 ? ToString (searchString )。
令 pos 为 ? ToIntegerOrInfinity (position )。
断言 :如果
position 为 undefined ,则 pos 为 0。
令 len 为 S 的长度。
令 start 为 clamping pos 介于 0 和
len 之间的结果。
令 result 为 StringIndexOf (S ,
searchStr , start )。
如果 result 为 not-found ,返回
-1 𝔽 。
返回 𝔽 (result )。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.10 String.prototype.isWellFormed ( )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
返回 IsStringWellFormedUnicode (S )。
22.1.3.11 String.prototype.lastIndexOf ( searchString
[ , position ] )
注 1
如果 searchString 作为子串 出现在将此对象转换为 String
后的结果中,且索引小于等于 position ,则返回最大的此类索引,否则返回
-1 𝔽 。如果 position 为
undefined ,则假定为字符串长度,即搜索整个字符串。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 searchStr 为 ? ToString (searchString )。
令 numPos 为 ? ToNumber (position )。
断言 :如果
position 为 undefined ,则 numPos 为
NaN 。
如果 numPos 为 NaN ,令 pos 为 +∞;否则,令
pos 为 ! ToIntegerOrInfinity (numPos )。
令 len 为 S 的长度。
令 searchLen 为 searchStr 的长度。
令 start 为 clamping pos 介于 0 和
len - searchLen 之间的结果。
令 result 为 StringLastIndexOf (S ,
searchStr , start )。
如果 result 为 not-found ,返回
-1 𝔽 。
返回 𝔽 (result )。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.12 String.prototype.localeCompare ( that [ ,
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现未包含 ECMA-402
API,则使用以下规范:
该方法返回一个除 NaN 以外的 Number,表示将 this 值(转换为字符串
S )与 that (转换为字符串 thatValue )进行实现定义 的本地敏感字符串比较的结果。该结果旨在与 宿主环境 当前区域设置的排序顺序 相对应,当 S 排在
thatValue 之前时为负,排在之后时为正,否则为零(表示 S 和 thatValue 之间无相对顺序)。
在执行比较前,该方法会按如下步骤准备字符串:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 thatValue 为 ? ToString (that )。
本方法的第二和第三个可选参数的含义在 ECMA-402 规范中定义;未包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
实际返回值为实现定义 ,以允许编码额外信息,但作为两个参数的方法时,要求作为一致的比较器 ,对所有字符串集合定义全序关系。该方法还要求根据 Unicode
标准识别和遵循规范等价,包括在比较可区分但规范等价的字符串时返回 +0 𝔽 。
注 1
此方法本身不适合作为 Array.prototype.sort 的参数,因为后者需要两个参数的函数。
注 2
此方法可依赖 ECMAScript 环境从宿主环境 获得的任意语言/区域敏感比较功能,并旨在按照宿主环境当前区域设置的习惯进行比较。但无论比较能力如何,本方法都必须根据
Unicode 标准识别和遵循规范等价——例如,以下比较都必须返回 +0 𝔽 :
"\u212B" .localeCompare ("A\u030A" )
"\u2126" .localeCompare ("\u03A9" )
"\u1E69" .localeCompare ("s\u0307\u0323" )
"\u1E0B\u0323" .localeCompare ("\u1E0D\u0307" )
"\u1100\u1161" .localeCompare ("\uAC00" )
关于规范等价的定义和讨论,参见 Unicode 标准第 2 章和第 3 章,以及 Unicode Standard Annex #15, Unicode
Normalization Forms 和 Unicode
Technical Note #5, Canonical Equivalence in Applications 。另见 Unicode Technical Standard #10, Unicode
Collation Algorithm 。
建议本方法不应遵循 Unicode 兼容等价或 Unicode 标准第 3 章第 3.7 节定义的兼容分解。
注 3
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.13 String.prototype.match ( regexp )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
如果 regexp 既不是 undefined 也不是 null ,则
令 matcher 为 ? GetMethod (regexp ,
%Symbol.match% )。
如果 matcher 不为 undefined ,则
返回 ? Call (matcher ,
regexp , « O »)。
令 S 为 ? ToString (O )。
令 rx 为 ? RegExpCreate (regexp ,
undefined )。
返回 ? Invoke (rx , %Symbol.match% , «
S »)。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.14 String.prototype.matchAll ( regexp )
该方法对将 this 值表示的字符串与 regexp 进行正则表达式匹配,并返回一个迭代器 ,该迭代器会产生匹配结果。每个匹配结果是一个数组,其第一个元素为匹配到的字符串片段,后跟任何捕获组匹配到的片段。如果正则表达式从未匹配,返回的迭代器不会产生任何匹配结果。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
如果 regexp 既不是 undefined 也不是 null ,则
令 isRegExp 为 ? IsRegExp (regexp )。
如果 isRegExp 为 true ,则
令 flags 为 ? Get (regexp ,
"flags" )。
执行 ? RequireObjectCoercible (flags )。
如果 ? ToString (flags )
不包含 "g" ,抛出 TypeError 异常。
令 matcher 为 ? GetMethod (regexp ,
%Symbol.matchAll% )。
如果 matcher 不为 undefined ,则
返回 ? Call (matcher ,
regexp , « O »)。
令 S 为 ? ToString (O )。
令 rx 为 ? RegExpCreate (regexp ,
"g" )。
返回 ? Invoke (rx , %Symbol.matchAll% , «
S »)。
注 1
此方法有意设计为泛型,不要求其 this 值为 String
对象。因此,可以转移到其他类型的对象上作为方法使用。
注 2
与 String.prototype.split
类似,String.prototype.matchAll 通常不应改变其输入。
22.1.3.15 String.prototype.normalize ( [ form ] )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
如果 form 为 undefined ,令 f 为
"NFC" 。
否则,令 f 为 ? ToString (form )。
如果 f 不是
"NFC" 、"NFD" 、"NFKC" 或
"NFKD" 之一,则抛出 RangeError 异常。
令 ns 为将 S 按 最新 Unicode
标准,Normalization Forms 中由 f 命名的规范形式规范化后的字符串值。
返回 ns 。
注
此方法有意设计为泛型,不要求其 this 值为 String 对象。因此可以转移到其他类型的对象上作为方法使用。
22.1.3.16 String.prototype.padEnd ( maxLength [ ,
fillString ] )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
返回 ? StringPaddingBuiltinsImpl (O ,
maxLength , fillString , end )。
22.1.3.17 String.prototype.padStart ( maxLength [ ,
fillString ] )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
返回 ? StringPaddingBuiltinsImpl (O ,
maxLength , fillString , start )。
22.1.3.17.1 StringPaddingBuiltinsImpl ( O ,
maxLength , fillString , placement )
抽象操作 StringPaddingBuiltinsImpl 接收参数 O (ECMAScript
语言值 )、maxLength (ECMAScript
语言值 )、fillString (ECMAScript 语言值 )和
placement (start 或
end ),返回字符串或抛出异常。调用时执行以下步骤:
令 S 为 ? ToString (O )。
令 intMaxLength 为 ℝ (? ToLength (maxLength ))。
令 stringLength 为 S 的长度。
如果 intMaxLength ≤ stringLength ,返回 S 。
如果 fillString 为 undefined ,设置 fillString
为仅包含码元 0x0020(空格)的字符串。
否则,设置 fillString 为 ? ToString (fillString )。
返回 StringPad (S ,
intMaxLength , fillString , placement )。
22.1.3.17.2 StringPad ( S , maxLength ,
fillString , placement )
抽象操作 StringPad 接收参数 S (字符串)、maxLength (非负整数 )、fillString (字符串)和
placement (start 或
end ),返回字符串。调用时执行以下步骤:
令 stringLength 为 S 的长度。
如果 maxLength ≤ stringLength ,返回 S 。
如果 fillString 为空字符串,返回 S 。
令 fillLen 为 maxLength - stringLength 。
令 truncatedStringFiller 为重复拼接 fillString 并截断为
fillLen 长度的字符串。
如果 placement 为 start ,返回 字符串拼接
truncatedStringFiller 和 S 的结果。
否则,返回 字符串拼接 S 和
truncatedStringFiller 的结果。
注 1
maxLength 参数会被限制,不能小于 S 的长度。
注 2
fillString 参数的默认值为 " " (仅包含码元 0x0020 空格的字符串)。
22.1.3.17.3 ToZeroPaddedDecimalString ( n ,
minLength )
抽象操作 ToZeroPaddedDecimalString 接收参数 n (非负整数 )和
minLength (非负整数 ),返回字符串。调用时执行以下步骤:
令 S 为 n 的字符串表示,格式为十进制数。
返回 StringPad (S ,
minLength , "0" , start )。
22.1.3.18 String.prototype.repeat ( count )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 n 为 ? ToIntegerOrInfinity (count )。
如果 n < 0 或 n = +∞,抛出 RangeError 异常。
如果 n = 0,返回空字符串。
返回由 S 拼接 n 次组成的字符串值。
注 1
此方法会创建由 this 值(转换为字符串)的码元重复 count 次组成的字符串值。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.19 String.prototype.replace ( searchValue ,
replaceValue )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
如果 searchValue 既不是 undefined 也不是
null ,则
令 replacer 为 ? GetMethod (searchValue ,
%Symbol.replace% )。
如果 replacer 不为 undefined ,则
返回 ? Call (replacer ,
searchValue , « O ,
replaceValue »)。
令 string 为 ? ToString (O )。
令 searchString 为 ? ToString (searchValue )。
令 functionalReplace 为 IsCallable (replaceValue )。
如果 functionalReplace 为 false ,则
将 replaceValue 设为 ? ToString (replaceValue )。
令 searchLength 为 searchString 的长度。
令 position 为 StringIndexOf (string ,
searchString , 0)。
如果 position 为 not-found ,返回 string 。
令 preceding 为 substring string 从 0 到
position 。
令 following 为 substring string 从
position + searchLength 。
如果 functionalReplace 为 true ,则
令 replacement 为 ? ToString (? Call (replaceValue ,
undefined , « searchString , 𝔽 (position ),
string »))。
否则,
断言 :replaceValue 是
String 。
令 captures 为新的空List 。
令 replacement 为 ! GetSubstitution (searchString ,
string , position , captures ,
undefined , replaceValue )。
返回 字符串拼接
preceding 、replacement 和 following 。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.19.1 GetSubstitution ( matched ,
str , position , captures , namedCaptures ,
replacementTemplate )
抽象操作 GetSubstitution 接收参数
matched (字符串)、str (字符串)、position (非负整数 )、captures (字符串或
undefined 的List )、namedCaptures (对象或
undefined )、replacementTemplate (字符串),返回字符串或抛出异常。此抽象操作中,十进制数字 是
0x0030 (DIGIT ZERO) 到 0x0039 (DIGIT NINE) 区间的码元。调用时执行以下步骤:
令 stringLength 为 str 的长度。
断言 :position ≤
stringLength 。
令 result 为空字符串。
令 templateRemainder 为 replacementTemplate 。
重复,直到 templateRemainder 为空字符串,
注:以下步骤隔离
ref (templateRemainder 的前缀),确定
refReplacement (其替换内容),然后将该替换内容追加到 result 。
如果 templateRemainder 以 "$$" 开头,则
令 ref 为 "$$" 。
令 refReplacement 为 "$" 。
否则,如果 templateRemainder 以 "$`" 开头,则
令 ref 为 "$`" 。
令 refReplacement 为 substring
str 从 0 到 position 。
否则,如果 templateRemainder 以 "$&" 开头,则
令 ref 为 "$&" 。
令 refReplacement 为 matched 。
否则,如果 templateRemainder 以
"$'" (0x0024(美元符号)后接 0x0027(撇号))开头,则
令 ref 为 "$'" 。
令 matchLength 为 matched 的长度。
令 tailPos 为 position +
matchLength 。
令 refReplacement 为 substring
str 从 min (tailPos ,
stringLength )。
注:tailPos 只有在该抽象操作由对 %RegExp.prototype% 的 %Symbol.replace%
内置方法调用,且对象的 "exec" 属性不是内置
%RegExp.prototype.exec% 时才会超过 stringLength 。
否则,如果 templateRemainder 以 "$" 后跟 1
个或多个十进制数字开头,则
如果 templateRemainder 以 "$" 后跟 2
个或更多十进制数字开头,令 digitCount 为 2,否则为 1。
令 digits 为 substring
templateRemainder 从 1 到 1 + digitCount 。
令 index 为 ℝ (StringToNumber (digits ))。
断言 :0 ≤ index ≤
99。
令 captureLen 为 captures 的元素个数。
如果 index > captureLen 且
digitCount = 2,则
注:两位数替换模式指定的索引超出捕获组数量时,视为一位数替换模式后跟一个字面数字。
令 digitCount 为 1。
令 digits 为 substring
digits 从 0 到 1。
令 index 为 ℝ (StringToNumber (digits ))。
令 ref 为 substring
templateRemainder 从 0 到 1 + digitCount 。
如果 1 ≤ index ≤ captureLen ,则
令 capture 为
captures [index - 1]。
如果 capture 为 undefined ,则
令 refReplacement 为空字符串。
否则,
令 refReplacement 为
capture 。
否则,
令 refReplacement 为 ref 。
否则,如果 templateRemainder 以 "$<" 开头,则
令 gtPos 为 StringIndexOf (templateRemainder ,
">" , 0)。
如果 gtPos 为 not-found 或
namedCaptures 为 undefined ,则
令 ref 为 "$<" 。
令 refReplacement 为 ref 。
否则,
令 ref 为 substring
templateRemainder 从 0 到 gtPos + 1。
令 groupName 为 substring
templateRemainder 从 2 到 gtPos 。
断言 :namedCaptures
是对象 。
令 capture 为 ? Get (namedCaptures ,
groupName )。
如果 capture 为 undefined ,则
令 refReplacement 为空字符串。
否则,
令 refReplacement 为 ? ToString (capture )。
否则,
令 ref 为 substring
templateRemainder 从 0 到 1。
令 refReplacement 为 ref 。
令 refLength 为 ref 的长度。
将 templateRemainder 设为 substring
templateRemainder 从 refLength 。
将 result 设为 字符串拼接
result 和 refReplacement 的结果。
返回 result 。
22.1.3.20 String.prototype.replaceAll ( searchValue ,
replaceValue )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
如果 searchValue 既不是 undefined 也不是
null ,则
令 isRegExp 为 ? IsRegExp (searchValue )。
如果 isRegExp 为 true ,则
令 flags 为 ? Get (searchValue ,
"flags" )。
执行 ? RequireObjectCoercible (flags )。
如果 ? ToString (flags )
不包含 "g" ,抛出 TypeError 异常。
令 replacer 为 ? GetMethod (searchValue ,
%Symbol.replace% )。
如果 replacer 不为 undefined ,则
返回 ? Call (replacer ,
searchValue , « O , replaceValue »)。
令 string 为 ? ToString (O )。
令 searchString 为 ? ToString (searchValue )。
令 functionalReplace 为 IsCallable (replaceValue )。
如果 functionalReplace 为 false ,则
将 replaceValue 设为 ? ToString (replaceValue )。
令 searchLength 为 searchString 的长度。
令 advanceBy 为 max (1, searchLength )。
令 matchPositions 为新的空 List 。
令 position 为 StringIndexOf (string ,
searchString , 0)。
重复,直到 position 为 not-found ,
将 position 添加到 matchPositions 。
将 position 设为 StringIndexOf (string ,
searchString , position + advanceBy )。
令 endOfLastMatch 为 0。
令 result 为空字符串。
对于 matchPositions 中的每个元素 p ,执行
令 preserved 为 substring string 从
endOfLastMatch 到 p 。
如果 functionalReplace 为 true ,则
令 replacement 为 ? ToString (? Call (replaceValue ,
undefined , « searchString , 𝔽 (p ),
string »))。
否则,
断言 :replaceValue
是
String 。
令 captures 为新的空List 。
令 replacement 为 ! GetSubstitution (searchString ,
string , p , captures ,
undefined , replaceValue )。
将 result 设为 字符串拼接
result 、preserved 和 replacement 的结果。
将 endOfLastMatch 设为 p + searchLength 。
如果 endOfLastMatch < string 的长度,则
将 result 设为 字符串拼接
result 和 substring string 从
endOfLastMatch 。
返回 result 。
22.1.3.21 String.prototype.search ( regexp )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
如果 regexp 既不是 undefined 也不是 null ,则
令 searcher 为 ? GetMethod (regexp ,
%Symbol.search% )。
如果 searcher 不为 undefined ,则
返回 ? Call (searcher ,
regexp , « O »)。
令 string 为 ? ToString (O )。
令 rx 为 ? RegExpCreate (regexp ,
undefined )。
返回 ? Invoke (rx , %Symbol.search% , «
string »)。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.22 String.prototype.slice ( start ,
end )
该方法返回将此对象转换为字符串后的子串 ,从索引 start 开始,到但不包括索引
end (或若 end 为 undefined ,则直到字符串末尾)。如果
start 为负,则视为 sourceLength +
start ,其中 sourceLength 是字符串长度。如果 end 为负,则视为
sourceLength + end 。结果是 String 值,而不是
String 对象。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 len 为 S 的长度。
令 intStart 为 ? ToIntegerOrInfinity (start )。
如果 intStart = -∞,令 from 为 0。
否则若 intStart < 0,令 from 为 max (len +
intStart , 0)。
否则,令 from 为 min (intStart , len )。
如果 end 为 undefined ,令 intEnd 为
len ;否则令 intEnd 为 ? ToIntegerOrInfinity (end )。
如果 intEnd = -∞,令 to 为 0。
否则若 intEnd < 0,令 to 为 max (len +
intEnd , 0)。
否则,令 to 为 min (intEnd , len )。
如果 from ≥ to ,返回空字符串。
返回 substring S 从 from 到
to 。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此可以转移到其他类型的对象上作为方法使用。
22.1.3.23 String.prototype.split ( separator ,
limit )
该方法返回一个数组,将此对象转换为字符串后的子串存储在其中。子串是通过从左到右查找 separator
的出现位置确定的;这些出现位置不会包含在返回数组的任何字符串中,而是用来分割字符串。separator 的值可以是任意长度的字符串,也可以是具有
%Symbol.split% 方法的对象(如 RegExp)。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
如果 separator 既不是 undefined 也不是
null ,则
令 splitter 为 ? GetMethod (separator ,
%Symbol.split% )。
如果 splitter 不为 undefined ,则
返回 ? Call (splitter ,
separator , « O , limit »)。
令 S 为 ? ToString (O )。
如果 limit 为 undefined ,令 lim 为 232
- 1;否则令 lim 为 ℝ (? ToUint32 (limit ))。
令 R 为 ? ToString (separator )。
如果 lim = 0,则
返回 CreateArrayFromList («
»)。
如果 separator 为 undefined ,则
返回 CreateArrayFromList («
S »)。
令 separatorLength 为 R 的长度。
如果 separatorLength = 0,则
令 strLen 为 S 的长度。
令 outLen 为 clamping lim 在 0 和
strLen 之间的结果。
令 head 为 substring S 从 0 到
outLen 。
令 codeUnits 为一个 List ,包含
head 的所有码元。
返回 CreateArrayFromList (codeUnits )。
如果 S 为空字符串,返回 CreateArrayFromList («
S »)。
令 substrings 为新的空 List 。
令 i 为 0。
令 j 为 StringIndexOf (S ,
R , 0)。
重复,直到 j 为 not-found ,
令 T 为 substring S 从
i 到 j 。
将 T 添加到 substrings 。
如果 substrings 的元素个数为 lim ,返回 CreateArrayFromList (substrings )。
将 i 设为 j + separatorLength 。
将 j 设为 StringIndexOf (S ,
R , i )。
令 T 为 substring S 从 i 。
将 T 添加到 substrings 。
返回 CreateArrayFromList (substrings )。
注 1
separator 的值可以为空字符串。在这种情况下,separator
不会匹配输入字符串开头或结尾的空子串 ,也不会匹配前一个分隔符匹配后结尾的空子串 。如果
separator
为空字符串,则字符串被拆分为单个码元元素;结果数组的长度等于字符串的长度,每个子串 只包含一个码元。
如果 this 值(或其转换结果)为空字符串,则结果取决于 separator
能否匹配空字符串。如果可以,结果数组不包含任何元素;否则,结果数组包含一个元素,即空字符串。
如果 separator 为 undefined ,结果数组只包含一个字符串,即
this 的值(转换为字符串)。如果 limit 不为
undefined ,则输出数组会被截断为不超过 limit 个元素。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.24 String.prototype.startsWith ( searchString
[ , position ] )
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 isRegExp 为 ? IsRegExp (searchString )。
如果 isRegExp 为 true ,抛出 TypeError 异常。
令 searchStr 为 ? ToString (searchString )。
令 len 为 S 的长度。
如果 position 为 undefined ,令 pos 为 0;否则令
pos 为 ? ToIntegerOrInfinity (position )。
令 start 为 clamping pos 在 0 和 len
之间的结果。
令 searchLength 为 searchStr 的长度。
如果 searchLength = 0,返回 true 。
令 end 为 start + searchLength 。
如果 end > len ,返回 false 。
令 substring 为 substring S 从 start 到
end 。
如果 substring 等于 searchStr ,返回 true 。
返回 false 。
注 1
如果 searchString (转换为字符串)的码元序列与本对象(转换为字符串)从 position
开始的对应码元相同,则返回 true ,否则返回 false 。
注 2
如果第一个参数是 RegExp 抛出异常,是为了允许后续标准版本定义支持此类参数值的扩展。
注 3
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.25 String.prototype.substring ( start ,
end )
该方法返回将此对象转换为字符串后的子串 ,从索引 start 开始,到但不包括字符串的索引
end (或若 end 为 undefined ,则直到字符串末尾)。结果是 String 值,而不是
String 对象。
如果任一参数为 NaN 或负数,则用零替换;如果任一参数严格大于字符串长度,则用字符串长度替换。
如果 start 严格大于 end ,则交换两者。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 len 为 S 的长度。
令 intStart 为 ? ToIntegerOrInfinity (start )。
如果 end 为 undefined ,令 intEnd 为
len ;否则令 intEnd 为 ? ToIntegerOrInfinity (end )。
令 finalStart 为 clamping intStart 在 0 和
len 之间的结果。
令 finalEnd 为 clamping intEnd 在 0 和
len 之间的结果。
令 from 为 min (finalStart ,
finalEnd )。
令 to 为 max (finalStart ,
finalEnd )。
返回 substring S 从 from 到
to 。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.26 String.prototype.toLocaleLowerCase ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现未包含 ECMA-402
API,则使用以下规范:
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
其行为与 toLowerCase 相同,但旨在根据 宿主环境 当前区域设置的惯例产生区域敏感的结果。仅在少数(如土耳其语)该语言规则与常规
Unicode 大小写映射冲突的情况下才会有差异。
该方法的可选参数含义由 ECMA-402 规范定义;未包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.27 String.prototype.toLocaleUpperCase ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现未包含 ECMA-402
API,则使用以下规范:
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
其行为与 toUpperCase 相同,但旨在根据 宿主环境 当前区域设置的惯例产生区域敏感的结果。仅在少数(如土耳其语)该语言规则与常规
Unicode 大小写映射冲突的情况下才会有差异。
该方法的可选参数含义由 ECMA-402 规范定义;未包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.28 String.prototype.toLowerCase ( )
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 sText 为 StringToCodePoints (S )。
令 lowerText 为根据 Unicode 默认大小写转换算法对 sText 执行 toLowercase。
令 L 为 CodePointsToString (lowerText )。
返回 L 。
结果必须依据 Unicode 字符数据库中的区域无关大小写映射得出(这不仅包括 UnicodeData.txt
文件,还包括伴随的 SpecialCasing.txt
文件中所有区域无关的映射)。
注 1
某些码点的大小写映射可能产生多个码点。在这种情况下,结果字符串的长度可能与源字符串不同。由于 toUpperCase 和
toLowerCase
都具有上下文相关行为,这些方法并不对称。换言之,s.toUpperCase().toLowerCase() 不一定等于
s.toLowerCase()。
注 2
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.29 String.prototype.toString ( )
调用该方法时,执行以下步骤:
返回 ? ThisStringValue (this
值)。
注
对于 String 对象,此方法恰好返回与 valueOf 方法相同的值。
22.1.3.30 String.prototype.toUpperCase ( )
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
其行为与 String.prototype.toLowerCase 完全相同,只是字符串使用 Unicode 默认大小写转换的 toUppercase
算法进行映射。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.31 String.prototype.toWellFormed ( )
该方法返回此对象的字符串表示,将所有不是代理对 一部分的前导代理项 和尾随代理项 替换为 U+FFFD(替换字符)。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 S 为 ? ToString (O )。
令 strLen 为 S 的长度。
令 k 为 0。
令 result 为空字符串。
重复,直到 k < strLen ,
令 cp 为 CodePointAt (S ,
k )。
如果 cp .[[IsUnpairedSurrogate]] 为
true ,则
将 result 设为 字符串拼接
result 和 0xFFFD(替换字符)的结果。
否则,
将 result 设为 字符串拼接
result 和 UTF16EncodeCodePoint (cp .[[CodePoint]] ) 的结果。
将 k 设为 k + cp .[[CodeUnitCount]] 。
返回 result 。
22.1.3.32 String.prototype.trim ( )
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
调用该方法时,执行以下步骤:
令 S 为 this 值。
返回 ? TrimString (S ,
start+end )。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.32.1 TrimString ( string , where
)
抽象操作 TrimString 接收参数 string (ECMAScript
语言值 )和
where (start 、end 或
start+end ),返回字符串或抛出异常。它将 string 解释为 UTF-16 编码码点序列,如
6.1.4
规定。调用时执行以下步骤:
令 str 为 ? RequireObjectCoercible (string )。
令 S 为 ? ToString (str )。
如果 where 为 start ,则
令 T 为 S 去除前导空白后的字符串值。
否则若 where 为 end ,则
令 T 为 S 去除尾随空白后的字符串值。
否则,
断言 :where 为
start+end 。
令 T 为 S 去除前导和尾随空白后的字符串值。
返回 T 。
空白的定义为 WhiteSpace 和
LineTerminator
的并集。在判断 Unicode 码点是否属于 Unicode 一般类别 “Space_Separator” (“Zs”) 时,码元序列被解释为 6.1.4 规定的
UTF-16 编码码点序列。
22.1.3.33 String.prototype.trimEnd ( )
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
调用该方法时,执行以下步骤:
令 S 为 this 值。
返回 ? TrimString (S ,
end )。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.34 String.prototype.trimStart ( )
该方法将 String 值作为 UTF-16 编码码点序列解释,如 6.1.4
中描述。
调用该方法时,执行以下步骤:
令 S 为 this 值。
返回 ? TrimString (S ,
start )。
注
此方法有意设计为泛型;它不要求其 this 值为 String 对象。因此,可以转移到其他类型的对象上作为方法使用。
22.1.3.35 String.prototype.valueOf ( )
调用该方法时,执行以下步骤:
返回 ? ThisStringValue (this
值)。
22.1.3.35.1 ThisStringValue ( value )
抽象操作 ThisStringValue 接收参数 value (ECMAScript
语言值 ),返回字符串或抛出异常。调用时执行以下步骤:
如果 value 是
String ,返回 value 。
如果 value 是对象 且 value 具有 [[StringData]] 内部槽,则
令 s 为 value .[[StringData]] 。
断言 :s 是
String 。
返回 s 。
抛出 TypeError 异常。
22.1.3.36 String.prototype [ %Symbol.iterator% ] ( )
该方法返回一个迭代器对象 ,用于遍历字符串值的每个码点,每次返回一个字符串值。
调用该方法时,执行以下步骤:
令 O 为 ? RequireObjectCoercible (this
值)。
令 s 为 ? ToString (O )。
令 closure 为新的抽象闭包 ,无参数,捕获
s ,并在被调用时执行以下步骤:
令 len 为 s 的长度。
令 position 为 0。
重复,直到 position < len ,
令 cp 为 CodePointAt (s ,
position )。
令 nextIndex 为 position + cp .[[CodeUnitCount]] 。
令 resultString 为 substring
s 从 position 到 nextIndex 。
将 position 设为 nextIndex 。
执行 ? GeneratorYield (CreateIteratorResultObject (resultString ,
false ))。
返回 undefined 。
返回 CreateIteratorFromClosure (closure ,
"%StringIteratorPrototype%" , %StringIteratorPrototype% )。
该方法的 "name" 属性值为 "[Symbol.iterator]" 。
22.1.4 String 实例的属性
String 实例是 String 特殊对象 ,并具有为此类对象规定的内部方法。String 实例继承自
String 原型对象
的属性。String 实例还具有 [[StringData]] 内部槽。[[StringData]] 内部槽是该 String 对象所表示的 String 值。
String 实例具有 "length" 属性,以及一组具有 整数索引 名称的可枚举属性。
22.1.4.1 length
该 String 对象所表示的 String 值中的元素数量。
一旦 String 对象被初始化,此属性不可更改。它具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
22.1.5 String 迭代器对象
String 迭代器 是表示对某个特定 String 实例对象的某次特定迭代的对象。String 迭代器对象没有命名的构造函数 。而是通过调用 String
实例对象的某些方法创建 String 迭代器对象。
22.1.5.1 %StringIteratorPrototype% 对象
%StringIteratorPrototype% 对象:
22.1.5.1.1 %StringIteratorPrototype%.next ( )
返回 ? GeneratorResume (this
值, empty ,
"%StringIteratorPrototype%" )。
22.1.5.1.2 %StringIteratorPrototype% [ %Symbol.toStringTag%
]
%Symbol.toStringTag% 属性的初始值为字符串值
"String Iterator" 。
该属性具有属性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true }。
22.2 RegExp(正则表达式)对象
RegExp 对象包含一个正则表达式和相关的标志(flags)。
注
正则表达式的形式和功能模仿了 Perl 5 编程语言中的正则表达式机制。
22.2.1 模式(Patterns)
RegExp 构造函数
对输入模式字符串应用以下语法。如果该语法无法将字符串解释为 Pattern 的展开,则会发生错误。
语法
Pattern [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Disjunction [UnicodeMode,
UnicodeSetsMode, NamedCaptureGroups]
::
Alternative [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Alternative [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
|
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Alternative [UnicodeMode,
UnicodeSetsMode, NamedCaptureGroups]
::
[empty]
Alternative [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Term [?UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Term [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
Assertion [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Atom [?UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Atom [?UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Quantifier
Assertion [UnicodeMode,
UnicodeSetsMode, NamedCaptureGroups]
::
^
$
\b
\B
(?=
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?!
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?<=
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?<!
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
Quantifier ::
QuantifierPrefix
QuantifierPrefix
?
QuantifierPrefix ::
*
+
?
{
DecimalDigits [~Sep]
}
{
DecimalDigits [~Sep]
,}
{
DecimalDigits [~Sep]
,
DecimalDigits [~Sep]
}
Atom [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
PatternCharacter
.
\
AtomEscape [?UnicodeMode,
?NamedCaptureGroups]
CharacterClass [?UnicodeMode,
?UnicodeSetsMode]
(
GroupSpecifier [?UnicodeMode] opt
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?
RegularExpressionModifiers
:
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?
RegularExpressionModifiers
-
RegularExpressionModifiers
:
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
RegularExpressionModifiers
::
[empty]
RegularExpressionModifiers
RegularExpressionModifier
RegularExpressionModifier
:: one of i
m s
SyntaxCharacter ::
one of ^ $ \
. * + ? (
) [ ] { }
|
PatternCharacter ::
SourceCharacter
but not SyntaxCharacter
AtomEscape [UnicodeMode,
NamedCaptureGroups] ::
DecimalEscape
CharacterClassEscape [?UnicodeMode]
CharacterEscape [?UnicodeMode]
[+NamedCaptureGroups]
k
GroupName [?UnicodeMode]
CharacterEscape [UnicodeMode]
::
ControlEscape
c
AsciiLetter
0
[lookahead ∉ DecimalDigit ]
HexEscapeSequence
RegExpUnicodeEscapeSequence [?UnicodeMode]
IdentityEscape [?UnicodeMode]
ControlEscape ::
one of f n r
t v
GroupSpecifier [UnicodeMode]
::
?
GroupName [?UnicodeMode]
GroupName [UnicodeMode]
::
<
RegExpIdentifierName [?UnicodeMode]
>
RegExpIdentifierName [UnicodeMode]
::
RegExpIdentifierStart [?UnicodeMode]
RegExpIdentifierName [?UnicodeMode]
RegExpIdentifierPart [?UnicodeMode]
RegExpIdentifierStart [UnicodeMode]
::
IdentifierStartChar
\
RegExpUnicodeEscapeSequence [+UnicodeMode]
[~UnicodeMode]
UnicodeLeadSurrogate
UnicodeTrailSurrogate
RegExpIdentifierPart [UnicodeMode]
::
IdentifierPartChar
\
RegExpUnicodeEscapeSequence [+UnicodeMode]
[~UnicodeMode]
UnicodeLeadSurrogate
UnicodeTrailSurrogate
RegExpUnicodeEscapeSequence [UnicodeMode]
:: [+UnicodeMode]
u
HexLeadSurrogate
\u
HexTrailSurrogate
[+UnicodeMode]
u
HexLeadSurrogate
[+UnicodeMode]
u
HexTrailSurrogate
[+UnicodeMode]
u
HexNonSurrogate
[~UnicodeMode]
u
Hex4Digits
[+UnicodeMode]
u{
CodePoint
}
UnicodeLeadSurrogate
::
any Unicode code point in the inclusive interval from U+D800 to
U+DBFF
UnicodeTrailSurrogate
::
any Unicode code point in the inclusive interval from U+DC00 to
U+DFFF
每个 \u HexTrailSurrogate ,其关联的 u
HexLeadSurrogate
存在歧义时,应将其关联到最近且本来没有对应 \u HexTrailSurrogate 的 u HexLeadSurrogate 。
HexLeadSurrogate ::
Hex4Digits
but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to
0xDBFF
HexNonSurrogate ::
Hex4Digits
but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to
0xDFFF
IdentityEscape [UnicodeMode]
:: [+UnicodeMode]
SyntaxCharacter
[+UnicodeMode]
/
[~UnicodeMode]
SourceCharacter
but not UnicodeIDContinue
DecimalEscape ::
NonZeroDigit
DecimalDigits [~Sep] opt
[lookahead ∉ DecimalDigit ]
CharacterClassEscape [UnicodeMode]
::
d
D
s
S
w
W
[+UnicodeMode]
p{
UnicodePropertyValueExpression
}
[+UnicodeMode]
P{
UnicodePropertyValueExpression
}
UnicodePropertyValueExpression
::
UnicodePropertyName
=
UnicodePropertyValue
LoneUnicodePropertyNameOrValue
UnicodePropertyName
::
UnicodePropertyNameCharacters
UnicodePropertyNameCharacters
::
UnicodePropertyNameCharacter
UnicodePropertyNameCharacters opt
UnicodePropertyValue
::
UnicodePropertyValueCharacters
LoneUnicodePropertyNameOrValue
::
UnicodePropertyValueCharacters
UnicodePropertyValueCharacters
::
UnicodePropertyValueCharacter
UnicodePropertyValueCharacters opt
UnicodePropertyValueCharacter
::
UnicodePropertyNameCharacter
DecimalDigit
UnicodePropertyNameCharacter
::
AsciiLetter
_
CharacterClass [UnicodeMode,
UnicodeSetsMode] ::
[
[lookahead ≠ ^ ]
ClassContents [?UnicodeMode,
?UnicodeSetsMode]
]
[^
ClassContents [?UnicodeMode,
?UnicodeSetsMode]
]
ClassContents [UnicodeMode,
UnicodeSetsMode] ::
[empty]
[~UnicodeSetsMode]
NonemptyClassRanges [?UnicodeMode]
[+UnicodeSetsMode]
ClassSetExpression
NonemptyClassRanges [UnicodeMode]
::
ClassAtom [?UnicodeMode]
ClassAtom [?UnicodeMode]
NonemptyClassRangesNoDash [?UnicodeMode]
ClassAtom [?UnicodeMode]
-
ClassAtom [?UnicodeMode]
ClassContents [?UnicodeMode,
~UnicodeSetsMode]
NonemptyClassRangesNoDash [UnicodeMode]
::
ClassAtom [?UnicodeMode]
ClassAtomNoDash [?UnicodeMode]
NonemptyClassRangesNoDash [?UnicodeMode]
ClassAtomNoDash [?UnicodeMode]
-
ClassAtom [?UnicodeMode]
ClassContents [?UnicodeMode,
~UnicodeSetsMode]
ClassAtom [UnicodeMode]
::
-
ClassAtomNoDash [?UnicodeMode]
ClassAtomNoDash [UnicodeMode]
::
SourceCharacter
but not one of \ or ] or
-
\
ClassEscape [?UnicodeMode]
ClassEscape [UnicodeMode]
::
b
[+UnicodeMode]
-
CharacterClassEscape [?UnicodeMode]
CharacterEscape [?UnicodeMode]
ClassSetExpression
::
ClassUnion
ClassIntersection
ClassSubtraction
ClassUnion ::
ClassSetRange
ClassUnion opt
ClassSetOperand
ClassUnion opt
ClassIntersection
::
ClassSetOperand
&&
[lookahead ≠ & ]
ClassSetOperand
ClassIntersection
&&
[lookahead ≠ & ]
ClassSetOperand
ClassSubtraction ::
ClassSetOperand
--
ClassSetOperand
ClassSubtraction
--
ClassSetOperand
ClassSetRange ::
ClassSetCharacter
-
ClassSetCharacter
ClassSetOperand ::
NestedClass
ClassStringDisjunction
ClassSetCharacter
NestedClass ::
[
[lookahead ≠ ^ ]
ClassContents [+UnicodeMode,
+UnicodeSetsMode]
]
[^
ClassContents [+UnicodeMode,
+UnicodeSetsMode]
]
\
CharacterClassEscape [+UnicodeMode]
注 1
ClassStringDisjunction
::
\q{
ClassStringDisjunctionContents
}
ClassStringDisjunctionContents
::
ClassString
ClassString
|
ClassStringDisjunctionContents
ClassString ::
[empty]
NonEmptyClassString
NonEmptyClassString
::
ClassSetCharacter
NonEmptyClassString opt
ClassSetCharacter
::
[lookahead ∉ ClassSetReservedDoublePunctuator ]
SourceCharacter
but not ClassSetSyntaxCharacter
\
CharacterEscape [+UnicodeMode]
\
ClassSetReservedPunctuator
\b
ClassSetReservedDoublePunctuator
:: one of &&
!! ## $$ %%
** ++ ,, ..
:: ;; << ==
>> ?? @@ ^^
`` ~~
ClassSetSyntaxCharacter
:: one of (
) [ ] { }
/ - \ |
ClassSetReservedPunctuator
:: one of &
- ! # % ,
: ; < =
> @ ` ~
注 2
本节中的多项产生式在 B.1.2 节中给出了替代定义。
22.2.1.1 静态语义:早期错误(Static Semantics: Early Errors)
注
Pattern :: Disjunction
QuantifierPrefix
::
{
DecimalDigits
,
DecimalDigits
}
Atom ::
(?
RegularExpressionModifiers
:
Disjunction
)
Atom ::
(?
RegularExpressionModifiers
-
RegularExpressionModifiers
:
Disjunction
)
AtomEscape ::
k
GroupName
AtomEscape ::
DecimalEscape
NonemptyClassRanges
::
ClassAtom
-
ClassAtom
ClassContents
NonemptyClassRangesNoDash
::
ClassAtomNoDash
-
ClassAtom
ClassContents
RegExpIdentifierStart
::
\
RegExpUnicodeEscapeSequence
RegExpIdentifierStart
::
UnicodeLeadSurrogate
UnicodeTrailSurrogate
RegExpIdentifierPart
::
\
RegExpUnicodeEscapeSequence
RegExpIdentifierPart
::
UnicodeLeadSurrogate
UnicodeTrailSurrogate
UnicodePropertyValueExpression
::
UnicodePropertyName
=
UnicodePropertyValue
UnicodePropertyValueExpression
::
LoneUnicodePropertyNameOrValue
CharacterClassEscape
::
P{
UnicodePropertyValueExpression
}
CharacterClass
::
[^
ClassContents
]
NestedClass
::
[^
ClassContents
]
ClassSetRange
::
ClassSetCharacter
-
ClassSetCharacter
22.2.1.2 静态语义:CountLeftCapturingParensWithin (node )
抽象操作 CountLeftCapturingParensWithin 接收参数 node (一个 解析节点 ),返回一个非负整数 。它返回 node 中左捕获括号的数量。左捕获括号 是任何与以下产生式的 (
终结符匹配的 ( 模式字符:
Atom ::
(
GroupSpecifier opt
Disjunction
)
注
调用时,执行以下步骤:
断言 :node 是 正则表达式模式语法 中的某个产生式的实例。
返回 node 内部所包含的以下解析节点的数量:
Atom ::
(
GroupSpecifier opt
Disjunction
)
解析节点
22.2.1.3 静态语义:CountLeftCapturingParensBefore (node )
抽象操作 CountLeftCapturingParensBefore 接收参数 node (一个 解析节点 ),返回一个非负整数 。它返回封闭模式中出现在 node
左侧的左捕获括号 的数量。
注
调用时,执行以下步骤:
断言 :node 是 正则表达式模式语法 中的某个产生式的实例。
令 pattern 为包含 node 的 Pattern 。
返回 pattern 内部,出现在 node 之前或包含 node 的以下解析节点的数量:
Atom ::
(
GroupSpecifier opt
Disjunction
)
解析节点
22.2.1.4 静态语义:MightBothParticipate (x , y )
抽象操作 MightBothParticipate 接收参数 x (一个 解析节点 )和 y (一个
解析节点 ),返回布尔值。调用时,执行以下步骤:
断言 :x 和 y 拥有同一个封闭的
Pattern 。
如果该封闭 Pattern 包含如下
Disjunction
::
Alternative
|
Disjunction
解析节点 ,使得 x 包含于
Alternative 中且
y 包含于派生的 Disjunction 中,或者 x 包含于派生的
Disjunction 中且
y 包含于 Alternative 中,则返回
false 。
返回 true 。
22.2.1.5 静态语义:CapturingGroupNumber
语法定向操作
CapturingGroupNumber 无参数,返回正整数 。
注
在以下产生式中分段定义:
DecimalEscape ::
NonZeroDigit
返回 NonZeroDigit 的
MV。
DecimalEscape ::
NonZeroDigit
DecimalDigits
令 n 为 DecimalDigits 中码点的数量。
返回 (NonZeroDigit 的
MV × 10n 加 DecimalDigits 的 MV)。
“NonZeroDigit 的 MV” 和
“DecimalDigits 的 MV” 的定义见
12.9.3 。
22.2.1.6 静态语义:IsCharacterClass
语法定向操作
IsCharacterClass 无参数,返回布尔值。
注
在以下产生式中分段定义:
ClassAtom ::
-
ClassAtomNoDash
::
SourceCharacter
但不是 \ 、] 或 - 之一
ClassEscape ::
b
-
CharacterEscape
返回 false 。
ClassEscape ::
CharacterClassEscape
返回 true 。
22.2.1.7 静态语义:CharacterValue
语法定向操作
CharacterValue 无参数,返回非负整数 。
注 1
在以下产生式中分段定义:
ClassAtom :: -
返回 U+002D(连字符 HYPHEN-MINUS)的数值。
ClassAtomNoDash
:: SourceCharacter 但不是
\ 、] 或 - 之一
令 ch 为 SourceCharacter 匹配的码点。
返回 ch 的数值。
ClassEscape ::
b
返回 U+0008(退格 BACKSPACE)的数值。
ClassEscape ::
返回 U+002D(连字符 HYPHEN-MINUS)的数值。
CharacterEscape
:: ControlEscape
按照 表 67 返回数值。
表 67: ControlEscape 码点数值
ControlEscape
数值
码点
Unicode 名称
符号
t
9
U+0009
CHARACTER TABULATION
<HT>
n
10
U+000A
LINE FEED (LF)
<LF>
v
11
U+000B
LINE TABULATION
<VT>
f
12
U+000C
FORM FEED (FF)
<FF>
r
13
U+000D
CARRIAGE RETURN (CR)
<CR>
CharacterEscape
::
c
AsciiLetter
令 ch 为 AsciiLetter 匹配的码点。
令 i 为 ch 的数值。
返回 i 除以 32 的余数。
CharacterEscape
::
0
[lookahead ∉ DecimalDigit ]
返回 U+0000(NULL)的数值。
注 2
\0 表示 <NUL> 字符,且不能后跟十进制数字。
CharacterEscape
:: HexEscapeSequence
返回 HexEscapeSequence 的 MV。
RegExpUnicodeEscapeSequence
::
u
HexLeadSurrogate
\u
HexTrailSurrogate
令 lead 为 CharacterValue
of HexLeadSurrogate 。
令 trail 为 CharacterValue
of HexTrailSurrogate 。
令 cp 为 UTF16SurrogatePairToCodePoint (lead ,
trail )。
返回 cp 的数值。
RegExpUnicodeEscapeSequence
::
u
Hex4Digits
返回 Hex4Digits 的 MV。
RegExpUnicodeEscapeSequence
::
u{
CodePoint
}
返回 CodePoint 的 MV。
HexLeadSurrogate
:: Hex4Digits
HexTrailSurrogate
:: Hex4Digits
HexNonSurrogate
:: Hex4Digits
返回 Hex4Digits 的 MV。
CharacterEscape
:: IdentityEscape
令 ch 为 IdentityEscape 匹配的码点。
返回 ch 的数值。
ClassSetCharacter
:: SourceCharacter 但不是
ClassSetSyntaxCharacter
令 ch 为 SourceCharacter 匹配的码点。
返回 ch 的数值。
ClassSetCharacter
::
\
ClassSetReservedPunctuator
令 ch 为 ClassSetReservedPunctuator
匹配的码点。
返回 ch 的数值。
ClassSetCharacter
:: \b
返回 U+0008(退格 BACKSPACE)的数值。
22.2.1.8 静态语义:MayContainStrings
语法定向操作
MayContainStrings 无参数,返回布尔值。它在以下产生式中分段定义:
CharacterClassEscape
::
d
D
s
S
w
W
P{
UnicodePropertyValueExpression
}
UnicodePropertyValueExpression
::
UnicodePropertyName
=
UnicodePropertyValue
NestedClass
::
[^
ClassContents
]
ClassContents
::
[empty]
NonemptyClassRanges
ClassSetOperand
::
ClassSetCharacter
返回 false 。
UnicodePropertyValueExpression
::
LoneUnicodePropertyNameOrValue
如果
source text
matched by
LoneUnicodePropertyNameOrValue
是 表
71 “属性名”列中列出的字符串的二进制属性,则返回 true 。
返回 false 。
ClassUnion
::
ClassSetRange
ClassUnion opt
如果 ClassUnion 存在,返回
MayContainStrings
of ClassUnion 。
返回 false 。
ClassUnion
::
ClassSetOperand
ClassUnion opt
如果 MayContainStrings
of ClassSetOperand 为
true ,返回 true 。
如果 ClassUnion 存在,返回
MayContainStrings
of ClassUnion 。
返回 false 。
ClassIntersection
::
ClassSetOperand
&&
ClassSetOperand
如果 MayContainStrings
of 第一个 ClassSetOperand 为
false ,返回 false 。
如果 MayContainStrings
of 第二个 ClassSetOperand 为
false ,返回 false 。
返回 true 。
ClassIntersection
::
ClassIntersection
&&
ClassSetOperand
如果 MayContainStrings
of ClassIntersection 为
false ,返回 false 。
如果 MayContainStrings
of ClassSetOperand 为
false ,返回 false 。
返回 true 。
ClassSubtraction
::
ClassSetOperand
--
ClassSetOperand
返回第一个 MayContainStrings
of ClassSetOperand 。
ClassSubtraction
::
ClassSubtraction
--
ClassSetOperand
返回 MayContainStrings
of ClassSubtraction 。
ClassStringDisjunctionContents
::
ClassString
|
ClassStringDisjunctionContents
如果 MayContainStrings
of ClassString 为
true ,返回 true 。
返回 MayContainStrings
of ClassStringDisjunctionContents 。
ClassString
::
[empty]
返回 true 。
ClassString
::
NonEmptyClassString
返回 MayContainStrings
of NonEmptyClassString 。
NonEmptyClassString
::
ClassSetCharacter
NonEmptyClassString opt
如果 NonEmptyClassString 存在,返回
true 。
返回 false 。
22.2.1.9 静态语义:GroupSpecifiersThatMatch
(thisGroupName )
抽象操作 GroupSpecifiersThatMatch 接收参数 thisGroupName (一个 GroupName 解析节点 ),返回 List 类型的 GroupSpecifier 解析节点 。调用时,执行如下步骤:
令 name 为 CapturingGroupName
of thisGroupName 。
令 pattern 为包含 thisGroupName 的 Pattern 。
令 result 为一个新的空 List 。
对于 pattern 包含的每个 GroupSpecifier gs ,执行:
如果 gs 的 CapturingGroupName
等于 name ,则:
将 gs 添加至 result 。
返回 result 。
22.2.1.10 静态语义:CapturingGroupName
语法定向操作
CapturingGroupName 无参数,返回字符串。它在以下产生式中分段定义:
GroupName ::
<
RegExpIdentifierName
>
令 idTextUnescaped 为 RegExpIdentifierCodePoints
of RegExpIdentifierName 。
返回 CodePointsToString (idTextUnescaped )。
22.2.1.11 静态语义:RegExpIdentifierCodePoints
语法定向操作
RegExpIdentifierCodePoints 无参数,返回码点 List 。它在以下产生式中分段定义:
RegExpIdentifierName
::
RegExpIdentifierStart
令 cp 为 RegExpIdentifierCodePoint
of RegExpIdentifierStart 。
返回 « cp »。
RegExpIdentifierName
::
RegExpIdentifierName
RegExpIdentifierPart
令 cps 为派生的 RegExpIdentifierCodePoints
of RegExpIdentifierName 。
令 cp 为 RegExpIdentifierCodePoint
of RegExpIdentifierPart 。
返回 list-concatenation of
cps 和 « cp »。
22.2.1.12 静态语义:RegExpIdentifierCodePoint
语法定向操作
RegExpIdentifierCodePoint 无参数,返回码点。它在以下产生式中分段定义:
RegExpIdentifierStart
::
IdentifierStartChar
返回 IdentifierStartChar 匹配的码点。
RegExpIdentifierPart
::
IdentifierPartChar
返回 IdentifierPartChar 匹配的码点。
RegExpIdentifierStart
::
\
RegExpUnicodeEscapeSequence
RegExpIdentifierPart
::
\
RegExpUnicodeEscapeSequence
返回数值为 CharacterValue
of RegExpUnicodeEscapeSequence
的码点。
RegExpIdentifierStart
::
UnicodeLeadSurrogate
UnicodeTrailSurrogate
RegExpIdentifierPart
::
UnicodeLeadSurrogate
UnicodeTrailSurrogate
令 lead 为 UnicodeLeadSurrogate
匹配的码点的数值所对应的码元。
令 trail 为 UnicodeTrailSurrogate
匹配的码点的数值所对应的码元。
返回 UTF16SurrogatePairToCodePoint (lead ,
trail )。
22.2.2 模式语义(Pattern Semantics)
正则表达式模式会按照下述过程被转换为一个 抽象闭包(Abstract
Closure) 。实现可以使用比下文所列更高效的算法,只要结果一致。该 抽象闭包 用作 RegExp 对象的 [[RegExpMatcher]] 内部槽的值。
如果一个 Pattern 的关联标志既不包含
u 也不包含 v,则它是 BMP 模式。否则,它是 Unicode 模式。BMP 模式会针对被解释为由处于基本多文种平面(BMP)范围内的
Unicode 码点组成的 16 位值序列的字符串进行匹配。Unicode 模式则针对被解释为用 UTF-16 编码的 Unicode 码点序列的字符串进行匹配。在描述 BMP
模式行为时,“character” 表示单个 16 位的 Unicode BMP 码点。在描述 Unicode 模式行为时,“character” 表示一个 UTF-16
编码的码点(6.1.4 )。无论哪种情况,“character
value” 都指对应非编码码点的数值。
Pattern 的语法和语义定义为其源文本为一个 List ,其中每个元素为 SourceCharacter ,对应一个 Unicode
码点。如果 BMP 模式包含了非 BMP 的 SourceCharacter ,则整个模式会被用 UTF-16
编码,并将该编码的各个码元作为 List 的元素。
注
例如,假设一个模式在源文本中表示为单个非 BMP 字符 U+1D11E(MUSICAL SYMBOL G CLEF)。作为 Unicode 模式解释时,它是一个仅包含该码点
U+1D11E 的元素(字符)List 。然而,作为 BMP
模式解释时,它会首先被 UTF-16 编码,得到两个元素的 List ,其码元分别为 0xD834
和 0xDD1E。
模式会以 ECMAScript 字符串值的形式传递给 RegExp 构造函数 ,其中非 BMP 字符已经用 UTF-16 编码。例如,该 MUSICAL
SYMBOL G CLEF 单字符模式,表达为字符串值时,是长度为 2 的字符串,其元素为 0xD834 和 0xDD1E 码元。因此,若作为包含两个模式字符的 BMP
模式处理,不需要再对字符串做转换;但若作为 Unicode 模式处理,则需用 UTF16SurrogatePairToCodePoint
得到仅含一个模式字符(码点 U+1D11E)的 List 。
实现不一定真的需要进行这些 UTF-16 的转换,但本规范要求,模式匹配的语义要如同进行了这些转换一样。
22.2.2.1 符号说明(Notation)
下述描述使用以下内部数据结构:
22.2.2.1.1 RegExp 记录(RegExp Records)
RegExp Record 是一个 Record ,用于存储 RegExp
在编译及可能的匹配期间需要的信息。
它包含如下字段:
表 68: RegExp Record 字段
字段名
值
含义
[[IgnoreCase]]
布尔值
指示 RegExp 标志中是否出现 "i"
[[Multiline]]
布尔值
指示 RegExp 标志中是否出现 "m"
[[DotAll]]
布尔值
指示 RegExp 标志中是否出现 "s"
[[Unicode]]
布尔值
指示 RegExp 标志中是否出现 "u"
[[UnicodeSets]]
布尔值
指示 RegExp 标志中是否出现 "v"
[[CapturingGroupsCount]]
非负整数
RegExp 模式中的 左捕获括号
的数量
22.2.2.2 运行时语义:CompilePattern
语法定向操作
CompilePattern 接收参数 rer (一个 RegExp Record ),返回一个
抽象闭包(Abstract Closure) ,该闭包接收一个字符
List 和一个非负 整数 ,返回一个 MatchState 或
failure 。它在以下产生式中分段定义:
Pattern ::
Disjunction
令 m 为 CompileSubpattern of Disjunction ,参数为
rer 和 forward 。
返回一个新 抽象闭包 ,参数为 (Input ,
index ),捕获 rer 和 m ,调用时执行以下步骤:
断言 :Input 为字符 List 。
断言 :0 ≤ index ≤
Input 的元素数量。
令 c 为一个新 MatcherContinuation ,参数
(y ),不捕获任何内容,调用时:
断言 :y 为 MatchState 。
返回 y 。
令 cap 为 rer .[[CapturingGroupsCount]] 个
undefined 的 List ,索引从
1 到 rer .[[CapturingGroupsCount]] 。
令 x 为 MatchState { [[Input]] : Input , [[EndIndex]] : index , [[Captures]] : cap }。
返回 m (x , c )。
注
Pattern 会被编译为 抽象闭包(Abstract Closure) 。RegExpBuiltinExec 可以将该过程应用于字符
List
及其偏移量,以判断模式是否会正好从该偏移处开始匹配,并在匹配时获得捕获括号的值。本节算法允许编译过程中抛出
SyntaxError ;但一旦编译成功,匹配时除非发生实现相关异常(如内存溢出)不会抛出异常。
22.2.2.3 运行时语义:CompileSubpattern
语法定向操作
CompileSubpattern 接收参数 rer (一个 RegExp Record )和
direction (forward 或 backward ),返回一个
Matcher 。
注 1
在以下产生式中分段定义:
Disjunction ::
Alternative
|
Disjunction
令 m1 为 CompileSubpattern of Alternative ,参数为
rer 和 direction 。
令 m2 为 CompileSubpattern of Disjunction ,参数为
rer 和 direction 。
返回 MatchTwoAlternatives (m1 ,
m2 )。
注 2
| 正则表达式操作符分隔两个备选项。模式首先尝试匹配左侧 Alternative (后接正则表达式剩余部分);如果失败,则尝试匹配右侧
Disjunction (后接剩余部分)。如果左侧 Alternative 、右侧 Disjunction
和剩余部分都有选择点,则会先穷尽剩余部分的所有选择,再移动到右侧。若左侧所有选择用尽,则会尝试右侧。被 | 跳过的部分中的捕获括号,其值为
undefined 而非字符串。例如:
/a|ab/.exec("abc")
返回结果为 "a" 而非 "ab" 。再例如:
/((a)|(ab))((c)|(bc))/.exec("abc")
返回数组:
["abc", "a", "a", undefined, "bc", undefined, "bc"]
而不是:
["abc", "ab", undefined, "ab", "c", "c", undefined]
两个备选项的尝试顺序与 direction 的值无关。
Alternative ::
[empty]
返回 EmptyMatcher ()。
Alternative ::
Alternative
Term
令 m1 为 CompileSubpattern of Alternative ,参数为
rer 和 direction 。
令 m2 为 CompileSubpattern of Term ,参数为 rer 和
direction 。
返回 MatchSequence (m1 ,
m2 , direction )。
注 3
连续的 Term 会尝试同时匹配
Input 的连续部分。当 direction 为 forward
时,若左、右和剩余部分都有选择点,则会先穷尽剩余、再穷尽右侧、最后再穷尽左侧的选择。当 direction 为
backward 时,左、右的顺序交换。
Term ::
Assertion
返回 CompileAssertion of Assertion ,参数为
rer 。
注 4
所得 Matcher 与 direction 无关。
Term ::
Atom
返回 CompileAtom of Atom ,参数为 rer 和
direction 。
Term ::
Atom
Quantifier
令 m 为 CompileAtom of Atom ,参数为 rer 和
direction 。
令 q 为 CompileQuantifier of Quantifier 。
断言 :q .[[Min]] ≤ q .[[Max]] 。
令 parenIndex 为 CountLeftCapturingParensBefore (Term )。
令 parenCount 为 CountLeftCapturingParensWithin (Atom )。
返回一个新 Matcher ,参数为 (x ,
c ),捕获 m 、q 、parenIndex 和
parenCount ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
返回 RepeatMatcher (m ,
q .[[Min]] , q .[[Max]] , q .[[Greedy]] , x , c ,
parenIndex , parenCount )。
22.2.2.3.1 RepeatMatcher (m , min ,
max , greedy , x , c , parenIndex ,
parenCount )
抽象操作 RepeatMatcher 接收参数 m (一个 Matcher )、min (非负
整数 )、max (非负 整数 或
+∞)、greedy (布尔值)、x (MatchState )、c (MatcherContinuation )、parenIndex (非负
整数 )、parenCount (非负 整数 ),返回一个 MatchState 或
failure 。调用时执行以下步骤:
如果 max = 0,返回 c (x )。
令 d 为一个新 MatcherContinuation ,参数
(y ),捕获
m 、min 、max 、greedy 、x 、c 、parenIndex 、parenCount ,调用时:
断言 :y 为 MatchState 。
如果 min = 0 且 y .[[EndIndex]] = x .[[EndIndex]] ,返回 failure 。
如果 min = 0,令 min2 为 0;否则,令 min2 为
min - 1。
如果 max = +∞,令 max2 为 +∞;否则,令 max2 为
max - 1。
返回 RepeatMatcher (m ,
min2 , max2 , greedy , y ,
c , parenIndex , parenCount )。
令 cap 为 x .[[Captures]] 的副本。
对于 整数 k ,在 闭区间 parenIndex + 1
到 parenIndex + parenCount ,令 cap [k ] =
undefined 。
令 Input 为 x .[[Input]] 。
令 e 为 x .[[EndIndex]] 。
令 xr 为 MatchState { [[Input]] : Input , [[EndIndex]] : e , [[Captures]] : cap }。
如果 min ≠ 0,返回 m (xr , d )。
如果 greedy 为 false ,则:
令 z 为 c (x )。
如果 z 不为 failure ,返回 z 。
返回 m (xr , d )。
令 z 为 m (xr , d )。
如果 z 不为 failure ,返回 z 。
返回 c (x )。
注 1
一个 Atom 后跟 Quantifier 时,会根据
Quantifier
指定的次数重复。Quantifier
可以是非贪婪的(尽量少匹配)或贪婪的(尽量多匹配)。重复的是 Atom 的模式本身,不同重复可匹配不同的输入子串。
注 2
如果 Atom
和剩余部分都有选择点,会先尽量多(或少,若非贪婪)匹配 Atom ,再穷尽剩余选择,然后再回溯到上一次重复。可以用这种选择点顺序写出求最大公约数的正则表达式。
注 3
RepeatMatcher 的 步骤
4 每次重复时都会清除 Atom 的捕获结果。
注 4
RepeatMatcher 的 2.b 指出:当已满足最小重复次数时,若
Atom
匹配空字符串,则不再继续重复,防止无限循环。
22.2.2.3.2 EmptyMatcher ( )
抽象操作 EmptyMatcher 无参数,返回一个 Matcher 。调用时执行以下步骤:
返回一个新 Matcher ,参数 (x ,
c ),不捕获任何内容,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
返回 c (x )。
22.2.2.3.3 MatchTwoAlternatives (m1 ,
m2 )
抽象操作 MatchTwoAlternatives 接收参数 m1 (Matcher )和
m2 (Matcher ),返回一个 Matcher 。调用时执行以下步骤:
返回一个新 Matcher ,参数 (x ,
c ),捕获 m1 和 m2 ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 r 为 m1 (x , c )。
若 r 非 failure ,返回 r 。
返回 m2 (x , c )。
22.2.2.3.4 MatchSequence (m1 , m2 ,
direction )
抽象操作 MatchSequence 接收参数 m1 (Matcher )、m2 (Matcher )、direction (forward
或 backward ),返回一个 Matcher 。调用时执行以下步骤:
如果 direction 为 forward ,则:
返回一个新 Matcher ,参数 (x ,
c ),捕获 m1 和 m2 ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),捕获 c 和 m2 ,调用时:
断言 :y 为
MatchState 。
返回 m2 (y , c )。
返回 m1 (x , d )。
否则:
断言 :direction 为
backward 。
返回一个新 Matcher ,参数 (x ,
c ),捕获 m1 和 m2 ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),捕获 c 和 m1 ,调用时:
断言 :y 为
MatchState 。
返回 m1 (y , c )。
返回 m2 (x , d )。
22.2.2.4 运行时语义:CompileAssertion
语法定向操作
CompileAssertion 接收参数 rer (RegExp Record ),返回一个 Matcher 。
注 1
在以下产生式中分段定义:
Assertion :: ^
返回一个新 Matcher ,参数 (x ,
c ),捕获 rer ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 Input = x .[[Input]] 。
令 e = x .[[EndIndex]] 。
如果 e = 0,或 rer .[[Multiline]]
为 true 且 Input [e - 1] 匹配 LineTerminator ,则:
返回 c (x )。
返回 failure 。
注 2
即使正则表达式使用 y 标志,^ 也只会在 Input 开头或(若
rer .[[Multiline]] 为
true )行首匹配。
Assertion :: $
返回一个新 Matcher ,参数 (x ,
c ),捕获 rer ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 Input = x .[[Input]] 。
令 e = x .[[EndIndex]] 。
令 InputLength = Input 的元素数量。
如果 e = InputLength ,或 rer .[[Multiline]] 为 true 且
Input [e ] 匹配 LineTerminator ,则:
返回 c (x )。
返回 failure 。
Assertion :: \b
返回一个新 Matcher ,参数 (x ,
c ),捕获 rer ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 Input = x .[[Input]] 。
令 e = x .[[EndIndex]] 。
令 a = IsWordChar (rer ,
Input , e - 1)。
令 b = IsWordChar (rer ,
Input , e )。
如果 a 为 true 且 b 为
false ,或 a 为 false 且
b 为 true ,返回 c (x )。
返回 failure 。
Assertion :: \B
返回一个新 Matcher ,参数 (x ,
c ),捕获 rer ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 Input = x .[[Input]] 。
令 e = x .[[EndIndex]] 。
令 a = IsWordChar (rer ,
Input , e - 1)。
令 b = IsWordChar (rer ,
Input , e )。
如果 a 和 b 同为 true 或同为
false ,返回 c (x )。
返回 failure 。
Assertion ::
(?=
Disjunction
)
令 m 为 CompileSubpattern of Disjunction ,参数为
rer 和 forward 。
返回一个新 Matcher ,参数 (x ,
c ),捕获 m ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),不捕获内容,调用时:
断言 :y 为 MatchState 。
返回 y 。
令 r 为 m (x , d )。
若 r 为 failure ,返回
failure 。
断言 :r 为 MatchState 。
令 cap = r .[[Captures]] 。
令 Input = x .[[Input]] 。
令 xe = x .[[EndIndex]] 。
令 z 为 MatchState { [[Input]] : Input , [[EndIndex]] : xe , [[Captures]] : cap }。
返回 c (z )。
注 3
形式 (?= Disjunction )
表示零宽度正向先行断言。其内部模式需在当前位置匹配成功,但当前位置不会推进。lookahead 内部无回溯。
Assertion ::
(?!
Disjunction
)
令 m 为 CompileSubpattern of Disjunction ,参数为
rer 和 forward 。
返回一个新 Matcher ,参数 (x ,
c ),捕获 m ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),不捕获内容,调用时:
断言 :y 为 MatchState 。
返回 y 。
令 r 为 m (x , d )。
若 r 非 failure ,返回
failure 。
返回 c (x )。
注 4
形式 (?! Disjunction )
表示零宽度负向先行断言。其内部模式需在当前位置匹配失败。
Assertion ::
(?<=
Disjunction
)
令 m 为 CompileSubpattern of Disjunction ,参数为
rer 和 backward 。
返回一个新 Matcher ,参数 (x ,
c ),捕获 m ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),不捕获内容,调用时:
断言 :y 为 MatchState 。
返回 y 。
令 r 为 m (x , d )。
若 r 为 failure ,返回
failure 。
断言 :r 为 MatchState 。
令 cap = r .[[Captures]] 。
令 Input = x .[[Input]] 。
令 xe = x .[[EndIndex]] 。
令 z 为 MatchState { [[Input]] : Input , [[EndIndex]] : xe , [[Captures]] : cap }。
返回 c (z )。
Assertion ::
(?<!
Disjunction
)
令 m 为 CompileSubpattern of Disjunction ,参数为
rer 和 backward 。
返回一个新 Matcher ,参数 (x ,
c ),捕获 m ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),不捕获内容,调用时:
断言 :y 为 MatchState 。
返回 y 。
令 r 为 m (x , d )。
若 r 非 failure ,返回
failure 。
返回 c (x )。
22.2.2.4.1 IsWordChar (rer , Input ,
e )
抽象操作 IsWordChar 接收参数 rer (RegExp
Record )、Input (字符 List )、e (整数 ),返回布尔值。调用时执行以下步骤:
令 InputLength = Input 的元素数量。
如果 e = -1 或 e = InputLength ,返回
false 。
令 c = Input [e ]。
如果 WordCharacters (rer )
包含 c ,返回 true 。
返回 false 。
22.2.2.5 运行时语义:CompileQuantifier
语法定向操作
CompileQuantifier 无参数,返回一个包含字段 [[Min]] (非负 整数 )、[[Max]] (非负 整数 或 +∞)、[[Greedy]] (布尔值)的
Record 。在以下产生式中分段定义:
Quantifier ::
QuantifierPrefix
令 qp 为 CompileQuantifierPrefix
of QuantifierPrefix 。
返回 Record { [[Min]] : qp .[[Min]] ,
[[Max]] : qp .[[Max]] ,
[[Greedy]] : true }。
Quantifier ::
QuantifierPrefix
?
令 qp 为 CompileQuantifierPrefix
of QuantifierPrefix 。
返回 Record { [[Min]] : qp .[[Min]] ,
[[Max]] : qp .[[Max]] ,
[[Greedy]] : false }。
22.2.2.6 运行时语义:CompileQuantifierPrefix
语法定向操作
CompileQuantifierPrefix 无参数,返回包含 [[Min]] (非负 整数 )、[[Max]] (非负 整数 或 +∞)字段的 Record 。在以下产生式中分段定义:
QuantifierPrefix
:: *
返回 Record { [[Min]] : 0, [[Max]] : +∞ }。
QuantifierPrefix
:: +
返回 Record { [[Min]] : 1, [[Max]] : +∞ }。
QuantifierPrefix
:: ?
返回 Record { [[Min]] : 0, [[Max]] : 1 }。
QuantifierPrefix
::
{
DecimalDigits
}
令 i 为 DecimalDigits 的 MV(见 12.9.3 )。
返回 Record { [[Min]] : i , [[Max]] :
i }。
QuantifierPrefix
::
{
DecimalDigits
,}
令 i 为 DecimalDigits 的 MV。
返回 Record { [[Min]] : i , [[Max]] : +∞
}。
QuantifierPrefix
::
{
DecimalDigits
,
DecimalDigits
}
令 i 为第一个 DecimalDigits 的 MV。
令 j 为第二个 DecimalDigits 的 MV。
返回 Record { [[Min]] : i , [[Max]] :
j }。
22.2.2.7 运行时语义:CompileAtom
语法定向操作
CompileAtom 接收参数 rer (RegExp Record )和
direction (forward 或 backward ),返回
Matcher 。
注 1
在以下产生式中分段定义:
Atom ::
PatternCharacter
令 ch 为 PatternCharacter 匹配的字符。
令 A 为仅包含字符 ch 的单元素 CharSet 。
返回 CharacterSetMatcher (rer ,
A , false , direction )。
Atom ::
.
令 A 为 AllCharacters (rer )。
如果 rer .[[DotAll]] 不为 true ,则:
从 A 中移除所有 LineTerminator 产生式右侧的码点对应的字符。
返回 CharacterSetMatcher (rer ,
A , false , direction )。
Atom ::
CharacterClass
令 cc 为 CompileCharacterClass of
CharacterClass ,参数为 rer 。
令 cs = cc .[[CharSet]] 。
如果 rer .[[UnicodeSets]] 为
false ,或 cs 的所有 CharSetElement
都是单字符(包括 cs 为空),则返回 CharacterSetMatcher (rer ,
cs , cc .[[Invert]] ,
direction )。
断言 :cc .[[Invert]] 为 false 。
令 lm 为 Matchers 的空 List 。
对于 cs 中每个包含多个字符的 CharSetElement
s (按长度降序遍历),执行:
令 cs2 为仅包含 s 最后一个码点的单元素 CharSet 。
令 m2 为 CharacterSetMatcher (rer ,
cs2 , false , direction )。
对于 s 中每个码点 c1 (从倒数第二个码点开始反向遍历),执行:
令 cs1 为仅包含 c1 的单元素 CharSet 。
令 m1 为 CharacterSetMatcher (rer ,
cs1 , false , direction )。
令 m2 = MatchSequence (m1 ,
m2 , direction )。
将 m2 添加到 lm 。
令 singles 为 cs 中所有单字符 CharSetElement
组成的 CharSet 。
将 CharacterSetMatcher (rer ,
singles , false , direction ) 添加到
lm 。
如果 cs 包含空序列,则将 EmptyMatcher () 添加到 lm 。
令 m2 为 lm 的最后一个 Matcher 。
对于 lm 中每个 Matcher
m1 (从倒数第二个元素开始反向遍历),执行:
令 m2 = MatchTwoAlternatives (m1 ,
m2 )。
返回 m2 。
Atom ::
(
GroupSpecifier opt
Disjunction
)
令 m 为 CompileSubpattern of Disjunction ,参数为
rer 和 direction 。
令 parenIndex = CountLeftCapturingParensBefore (Atom )。
返回一个新 Matcher ,参数 (x ,
c ),捕获 direction 、m 、parenIndex ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 d 为一个新 MatcherContinuation ,参数
(y ),捕获
x 、c 、direction 、parenIndex ,调用时:
断言 :y 为 MatchState 。
令 cap 为 y .[[Captures]] 的副本。
令 Input = x .[[Input]] 。
令 xe = x .[[EndIndex]] 。
令 ye = y .[[EndIndex]] 。
如果 direction 为 forward ,则:
断言 :xe ≤ ye 。
令 r 为 CaptureRange { [[StartIndex]] : xe , [[EndIndex]] : ye }。
否则:
断言 :direction 为
backward 。
断言 :ye ≤ xe 。
令 r 为 CaptureRange { [[StartIndex]] : ye , [[EndIndex]] : xe }。
设置 cap [parenIndex + 1] = r 。
令 z 为 MatchState { [[Input]] : Input , [[EndIndex]] : ye , [[Captures]] : cap }。
返回 c (z )。
返回 m (x , d )。
注 2
形如 ( Disjunction )
的括号既用于分组,也用于保存匹配结果。可以通过反向引用、替换字符串或结果数组使用该结果。用 (?: ... )
可禁用捕获行为。
Atom ::
(?
RegularExpressionModifiers
:
Disjunction
)
令 addModifiers 为 source text
matched by RegularExpressionModifiers 。
令 removeModifiers 为空字符串。
令 modifiedRer = UpdateModifiers (rer ,
CodePointsToString (addModifiers ),
removeModifiers )。
返回 CompileSubpattern of Disjunction ,参数为
modifiedRer 和 direction 。
Atom ::
(?
RegularExpressionModifiers
-
RegularExpressionModifiers
:
Disjunction
)
令 addModifiers 为 source text
matched by 第一个 RegularExpressionModifiers 。
令 removeModifiers 为 source text
matched by 第二个 RegularExpressionModifiers 。
令 modifiedRer = UpdateModifiers (rer ,
CodePointsToString (addModifiers ),
CodePointsToString (removeModifiers ))。
返回 CompileSubpattern of Disjunction ,参数为
modifiedRer 和 direction 。
AtomEscape ::
DecimalEscape
令 n 为 CapturingGroupNumber
of DecimalEscape 。
断言 :n ≤ rer .[[CapturingGroupsCount]] 。
返回 BackreferenceMatcher (rer ,
« n », direction )。
注 3
形如 \ 后跟非零十进制数字 n 的转义序列,匹配第 n 个捕获括号的结果。括号数不足 n
是错误。若 n 个括号有但第 n 个未捕获内容,则反向引用总是成功。
AtomEscape ::
CharacterEscape
令 cv 为 CharacterValue
of CharacterEscape 。
令 ch 为字符值为 cv 的字符。
令 A 为仅包含字符 ch 的单元素 CharSet 。
返回 CharacterSetMatcher (rer ,
A , false , direction )。
AtomEscape ::
CharacterClassEscape
令 cs 为 CompileToCharSet of CharacterClassEscape ,参数为
rer 。
如果 rer .[[UnicodeSets]] 为
false ,或 cs 的所有 CharSetElement
都是单字符(包括 cs 为空),则返回 CharacterSetMatcher (rer ,
cs , false , direction )。
令 lm 为 Matchers 的空 List 。
对于 cs 中每个包含多个字符的 CharSetElement
s (按长度降序遍历),执行:
令 cs2 为仅包含 s 最后一个码点的单元素 CharSet 。
令 m2 为 CharacterSetMatcher (rer ,
cs2 , false , direction )。
对于 s 中每个码点 c1 (从倒数第二个码点开始反向遍历),执行:
令 cs1 为仅包含 c1 的单元素 CharSet 。
令 m1 为 CharacterSetMatcher (rer ,
cs1 , false , direction )。
令 m2 = MatchSequence (m1 ,
m2 , direction )。
将 m2 添加到 lm 。
令 singles 为 cs 中所有单字符 CharSetElement
组成的 CharSet 。
将 CharacterSetMatcher (rer ,
singles , false , direction ) 添加到
lm 。
如果 cs 包含空序列,则将 EmptyMatcher () 添加到 lm 。
令 m2 为 lm 的最后一个 Matcher 。
对于 lm 中每个 Matcher
m1 (从倒数第二个元素开始反向遍历),执行:
令 m2 = MatchTwoAlternatives (m1 ,
m2 )。
返回 m2 。
AtomEscape ::
k
GroupName
令 matchingGroupSpecifiers 为 GroupSpecifiersThatMatch (GroupName )。
令 parenIndices 为一个新的空 List 。
对于 matchingGroupSpecifiers 中的每一个 GroupSpecifier
groupSpecifier ,执行:
令 parenIndex = CountLeftCapturingParensBefore (groupSpecifier )。
将 parenIndex 添加到 parenIndices 。
返回 BackreferenceMatcher (rer ,
parenIndices , direction )。
22.2.2.7.1 CharacterSetMatcher (rer ,
A , invert , direction )
抽象操作 CharacterSetMatcher 接收参数 rer (RegExp
Record )、A (CharSet )、invert (布尔值)、direction (forward
或 backward ),返回 Matcher 。调用时执行如下步骤:
如果 rer .[[UnicodeSets]] 为
true ,则:
断言 :invert 为
false 。
断言 :A 的每个 CharSetElement 都是单字符。
返回一个新 Matcher ,参数 (x ,
c ),捕获
rer 、A 、invert 、direction ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 Input = x .[[Input]] 。
令 e = x .[[EndIndex]] 。
若 direction 为 forward ,令 f =
e + 1。
否则,令 f = e - 1。
令 InputLength = Input 的元素数量。
若 f < 0 或 f > InputLength ,返回
failure 。
令 index = min (e , f )。
令 ch = Input [index ]。
令 cc = Canonicalize (rer ,
ch )。
如果存在 A 中仅含字符 a 的 CharSetElement ,且
Canonicalize (rer ,
a ) 等于 cc ,则 found =
true ,否则 found = false 。
若 invert 为 false 且 found 为
false ,返回 failure 。
若 invert 为 true 且 found 为
true ,返回 failure 。
令 cap = x .[[Captures]] 。
令 y = MatchState { [[Input]] : Input , [[EndIndex]] : f , [[Captures]] : cap }。
返回 c (y )。
22.2.2.7.2 BackreferenceMatcher (rer ,
ns , direction )
抽象操作 BackreferenceMatcher 接收参数 rer (RegExp
Record )、ns (正 整数 的 List )、direction (forward
或 backward ),返回 Matcher 。调用时执行如下步骤:
返回一个新 Matcher ,参数 (x ,
c ),捕获 rer 、ns 、direction ,调用时:
断言 :x 为 MatchState 。
断言 :c 为 MatcherContinuation 。
令 Input = x .[[Input]] 。
令 cap = x .[[Captures]] 。
令 r = undefined 。
对于 ns 中的每个 整数 n ,执行:
若 cap [n ] 非 undefined ,则:
断言 :r 为
undefined 。
令 r = cap [n ]。
若 r 为 undefined ,返回
c (x )。
令 e = x .[[EndIndex]] 。
令 rs = r .[[StartIndex]] 。
令 re = r .[[EndIndex]] 。
令 len = re - rs 。
若 direction 为 forward ,令 f =
e + len 。
否则,令 f = e - len 。
令 InputLength = Input 的元素数量。
若 f < 0 或 f > InputLength ,返回
failure 。
令 g = min (e , f )。
若存在 0(含)到 len (不含)间的 整数 i ,使得
Canonicalize (rer ,
Input [rs +i ]) ≠ Canonicalize (rer ,
Input [g +i ]),返回
failure 。
令 y = MatchState { [[Input]] : Input , [[EndIndex]] : f , [[Captures]] : cap }。
返回 c (y )。
22.2.2.7.3 Canonicalize (rer , ch )
抽象操作 Canonicalize 接收参数 rer (RegExp
Record )、ch (字符),返回一个字符。调用时执行如下步骤:
若 HasEitherUnicodeFlag (rer )
为 true 且 rer .[[IgnoreCase]] 为 true ,则:
若 CaseFolding.txt
提供了 ch 的简单或通用大小写折叠映射,则返回应用该映射后的 ch 。
返回 ch 。
若 rer .[[IgnoreCase]] 为
false ,返回 ch 。
断言 :ch 是 UTF-16 码元。
令 cp 为 ch 的数值对应的码点。
令 u 为根据 Unicode 默认大小写转换算法 toUppercase(« cp »)。
令 uStr = CodePointsToString (u )。
若 uStr 长度 ≠ 1,返回 ch 。
令 cu = uStr 的唯一码元。
若 ch 数值 ≥ 128 且 cu 数值 < 128,返回 ch 。
返回 cu 。
注
当 HasEitherUnicodeFlag (rer )
为 true 且大小写不敏感时,所有字符都用 Unicode
标准的简单大小写折叠映射进行大小写折叠再比较。简单映射总是映射为单一码点(如 ß 不会变为 ss 或
SS)。但部分非Basic Latin字符可映射为Basic Latin内字符,如 ſ 会折叠为
s,K 会折叠为 k,因此如 /[a-z]/ui
可匹配这些字符。
当 HasEitherUnicodeFlag (rer )
为 false 时,映射基于 Unicode 默认大小写转换算法的 toUppercase,而不是
toCasefold,存在差异。例如 Ω(U+2126)用 toUppercase 仍为自身,但 toCasefold 会变为
ω。所以 "\u2126" 能被 /[ω]/ui 匹配,不能被
/[ω]/i 匹配。非Basic Latin的字符不会映射到Basic Latin内字符。
22.2.2.7.4 UpdateModifiers (rer , add ,
remove )
抽象操作 UpdateModifiers 接收参数 rer (RegExp
Record )、add (字符串)、remove (字符串),返回一个 RegExp
Record 。调用时执行如下步骤:
断言 :add 与 remove
没有公共元素。
令 ignoreCase = rer .[[IgnoreCase]] 。
令 multiline = rer .[[Multiline]] 。
令 dotAll = rer .[[DotAll]] 。
令 unicode = rer .[[Unicode]] 。
令 unicodeSets = rer .[[UnicodeSets]] 。
令 capturingGroupsCount = rer .[[CapturingGroupsCount]] 。
如果 remove 包含 "i" ,则令 ignoreCase =
false 。
否则若 add 包含 "i" ,则令 ignoreCase =
true 。
如果 remove 包含 "m" ,则令 multiline =
false 。
否则若 add 包含 "m" ,则令 multiline =
true 。
如果 remove 包含 "s" ,则令 dotAll =
false 。
否则若 add 包含 "s" ,则令 dotAll =
true 。
返回 RegExp Record {
[[IgnoreCase]] : ignoreCase ,
[[Multiline]] : multiline ,
[[DotAll]] : dotAll ,
[[Unicode]] : unicode ,
[[UnicodeSets]] : unicodeSets ,
[[CapturingGroupsCount]] :
capturingGroupsCount
}。
22.2.2.8 运行时语义:CompileCharacterClass
语法定向操作
CompileCharacterClass 接收参数 rer (RegExp Record ),返回含字段 [[CharSet]] (CharSet )和 [[Invert]] (布尔值)的 Record 。在以下产生式中分段定义:
CharacterClass ::
[
ClassContents
]
令 A 为 CompileToCharSet of ClassContents ,参数为
rer 。
返回 Record { [[CharSet]] : A , [[Invert]] : false }。
CharacterClass ::
[^
ClassContents
]
令 A 为 CompileToCharSet of ClassContents ,参数为
rer 。
如果 rer .[[UnicodeSets]] 为
true ,则:
返回 Record {
[[CharSet]] : CharacterComplement (rer ,
A ), [[Invert]] : false }。
返回 Record { [[CharSet]] : A , [[Invert]] : true }。
22.2.2.9 运行时语义:CompileToCharSet
语法定向操作
CompileToCharSet 接收参数 rer (RegExp Record ),返回 CharSet 。
注 1
在以下产生式中分段定义:
ClassContents ::
[empty]
返回空 CharSet 。
NonemptyClassRanges
::
ClassAtom
NonemptyClassRangesNoDash
令 A = CompileToCharSet of ClassAtom ,参数为
rer 。
令 B = CompileToCharSet of NonemptyClassRangesNoDash ,参数为
rer 。
返回 A 与 B 的并集。
NonemptyClassRanges
::
ClassAtom
-
ClassAtom
ClassContents
令 A = CompileToCharSet of 第一个 ClassAtom ,参数为
rer 。
令 B = CompileToCharSet of 第二个 ClassAtom ,参数为
rer 。
令 C = CompileToCharSet of ClassContents ,参数为
rer 。
令 D = CharacterRange (A ,
B )。
返回 D 与 C 的并集。
NonemptyClassRangesNoDash
::
ClassAtomNoDash
NonemptyClassRangesNoDash
令 A = CompileToCharSet of ClassAtomNoDash ,参数为
rer 。
令 B = CompileToCharSet of NonemptyClassRangesNoDash ,参数为
rer 。
返回 A 与 B 的并集。
NonemptyClassRangesNoDash
::
ClassAtomNoDash
-
ClassAtom
ClassContents
令 A = CompileToCharSet of ClassAtomNoDash ,参数为
rer 。
令 B = CompileToCharSet of ClassAtom ,参数为
rer 。
令 C = CompileToCharSet of ClassContents ,参数为
rer 。
令 D = CharacterRange (A ,
B )。
返回 D 与 C 的并集。
注 2
ClassContents
可扩展为单个 ClassAtom 或由两个
ClassAtom
用连字符分隔的区间。后者情况下,ClassContents 包含两个 ClassAtom (含)之间的所有字符;如其中任一不是单字符(如
\w),或左端大于右端,则为错误。
注 3
即使忽略大小写,区间两端字符的大小写在区间确定时依然重要。例如 /[E-F]/i 只匹配 E,
F, e, f,而 /[E-f]/i 匹配 Basic
Latin 字母及 [, \, ], ^,
_, `。
注 4
- 可被当作字面量或区间。若在 ClassContents 首尾、区间端点、或区间后,视为字面量。
ClassAtom ::
-
返回仅包含字符 - U+002D (HYPHEN-MINUS) 的 CharSet 。
ClassAtomNoDash
::
SourceCharacter
但不能是 \ 、] 或 -
返回仅包含 SourceCharacter 匹配字符的 CharSet 。
ClassEscape ::
b
-
CharacterEscape
令 cv 为本 ClassEscape 的 CharacterValue 。
令 c 为字符值为 cv 的字符。
返回仅包含字符 c 的 CharSet 。
注 5
ClassAtom
可使用正则中允许的转义序列,除 \b、\B 和反向引用外。类中 \b
表示退格符,\B 和反向引用会报错。在 ClassAtom 使用反向引用是错误的。
CharacterClassEscape
::
d
返回包含字符 0 到 9 的十元素 CharSet 。
CharacterClassEscape
::
D
令 S 为 CharacterClassEscape ::
d
返回的 CharSet 。
返回 CharacterComplement (rer ,
S )。
CharacterClassEscape
::
s
返回包含 WhiteSpace 或
LineTerminator
产生式右侧所有码点的 CharSet 。
CharacterClassEscape
::
S
令 S 为 CharacterClassEscape ::
s
返回的 CharSet 。
返回 CharacterComplement (rer ,
S )。
CharacterClassEscape
::
w
返回 MaybeSimpleCaseFolding (rer ,
WordCharacters (rer ))。
CharacterClassEscape
::
W
令 S 为 CharacterClassEscape ::
w
返回的 CharSet 。
返回 CharacterComplement (rer ,
S )。
CharacterClassEscape
::
p{
UnicodePropertyValueExpression
}
返回 CompileToCharSet of UnicodePropertyValueExpression ,参数为
rer 。
CharacterClassEscape
::
P{
UnicodePropertyValueExpression
}
令 S 为 CompileToCharSet of UnicodePropertyValueExpression ,参数为
rer 。
断言 :S 仅包含单一码点。
返回 CharacterComplement (rer ,
S )。
UnicodePropertyValueExpression
::
UnicodePropertyName
=
UnicodePropertyValue
令 ps 为 source text
matched by UnicodePropertyName 。
令 p 为 UnicodeMatchProperty (rer ,
ps )。
断言 :p 是 表 69 “Property
name and aliases” 列中列出的 Unicode 属性名 或属性别名。
令 vs 为 source text
matched by UnicodePropertyValue 。
令 v 为 UnicodeMatchPropertyValue (p ,
vs )。
令 A 为包含所有在字符数据库定义中具有属性 p 且值为 v 的 Unicode 码点的
CharSet 。
返回 MaybeSimpleCaseFolding (rer ,
A )。
UnicodePropertyValueExpression
::
LoneUnicodePropertyNameOrValue
令 s 为 source text
matched by LoneUnicodePropertyNameOrValue 。
如果 UnicodeMatchPropertyValue (General_Category,
s ) 是 PropertyValueAliases.txt
中 General_Category (gc) 属性的 Unicode 属性值或属性值别名,则:
返回包含所有字符数据库定义中属性 “General_Category” 值为 s 的 Unicode 码点的 CharSet 。
令 p 为 UnicodeMatchProperty (rer ,
s )。
断言 :p 是 表 70 “Property name
and aliases” 列中列出的二值 Unicode 属性或二值属性别名,或 表 71
“Property name” 列中列出的字符串的二值 Unicode 属性。
令 A 为包含所有字符数据库定义中属性 p 值为 “True” 的 CharSetElements 的 CharSet 。
返回 MaybeSimpleCaseFolding (rer ,
A )。
ClassUnion ::
ClassSetRange
ClassUnion opt
令 A 为 CompileToCharSet of ClassSetRange ,参数为
rer 。
如果 ClassUnion 存在,则:
令 B 为 CompileToCharSet of ClassUnion ,参数为
rer 。
返回 CharSets A 与
B 的并集。
返回 A 。
ClassUnion ::
ClassSetOperand
ClassUnion opt
令 A 为 CompileToCharSet of ClassSetOperand ,参数为
rer 。
如果 ClassUnion 存在,则:
令 B 为 CompileToCharSet of ClassUnion ,参数为
rer 。
返回 CharSets A 与
B 的并集。
返回 A 。
ClassIntersection
::
ClassSetOperand
&&
ClassSetOperand
令 A 为 CompileToCharSet of 第一个 ClassSetOperand ,参数为
rer 。
令 B 为 CompileToCharSet of 第二个 ClassSetOperand ,参数为
rer 。
返回 CharSets A 与 B
的交集。
ClassIntersection
::
ClassIntersection
&&
ClassSetOperand
令 A 为 CompileToCharSet of ClassIntersection ,参数为
rer 。
令 B 为 CompileToCharSet of ClassSetOperand ,参数为
rer 。
返回 CharSets A 与 B
的交集。
ClassSubtraction
::
ClassSetOperand
--
ClassSetOperand
令 A 为第一个 CompileToCharSet of ClassSetOperand ,参数为
rer 。
令 B 为第二个 CompileToCharSet of ClassSetOperand ,参数为
rer 。
返回包含所有属于 A 但不属于 B 的 CharSetElements 的 CharSet 。
ClassSubtraction
::
ClassSubtraction
--
ClassSetOperand
令 A 为 CompileToCharSet of ClassSubtraction ,参数为
rer 。
令 B 为 CompileToCharSet of ClassSetOperand ,参数为
rer 。
返回包含所有属于 A 但不属于 B 的 CharSetElements 的 CharSet 。
ClassSetRange ::
ClassSetCharacter
-
ClassSetCharacter
令 A 为第一个 CompileToCharSet of ClassSetCharacter ,参数为
rer 。
令 B 为第二个 CompileToCharSet of ClassSetCharacter ,参数为
rer 。
返回 MaybeSimpleCaseFolding (rer ,
CharacterRange (A ,
B ))。
注 6
结果通常包含两个或更多区间。当 UnicodeSets 为 true 且 IgnoreCase 为
true 时,MaybeSimpleCaseFolding (rer ,
[Ā-č]) 只包含该区间中奇数码点。
ClassSetOperand
::
ClassSetCharacter
令 A 为 CompileToCharSet of ClassSetCharacter ,参数为
rer 。
返回 MaybeSimpleCaseFolding (rer ,
A )。
ClassSetOperand
::
ClassStringDisjunction
令 A 为 CompileToCharSet of ClassStringDisjunction ,参数为
rer 。
返回 MaybeSimpleCaseFolding (rer ,
A )。
ClassSetOperand
::
NestedClass
返回 CompileToCharSet of NestedClass ,参数为
rer 。
NestedClass ::
[
ClassContents
]
返回 CompileToCharSet of ClassContents ,参数为
rer 。
NestedClass ::
[^
ClassContents
]
令 A 为 CompileToCharSet of ClassContents ,参数为
rer 。
返回 CharacterComplement (rer ,
A )。
NestedClass ::
\
CharacterClassEscape
返回 CompileToCharSet of CharacterClassEscape ,参数为
rer 。
ClassStringDisjunction
::
\q{
ClassStringDisjunctionContents
}
返回 CompileToCharSet of ClassStringDisjunctionContents ,参数为
rer 。
ClassStringDisjunctionContents
::
ClassString
令 s 为 CompileClassSetString of
ClassString ,参数为
rer 。
返回仅包含字符串 s 的 CharSet 。
ClassStringDisjunctionContents
::
ClassString
|
ClassStringDisjunctionContents
令 s 为 CompileClassSetString of
ClassString ,参数为
rer 。
令 A 为仅包含字符串 s 的 CharSet 。
令 B 为 CompileToCharSet of ClassStringDisjunctionContents ,参数为
rer 。
返回 CharSets A 与 B
的并集。
ClassSetCharacter
::
SourceCharacter
但不能是 ClassSetSyntaxCharacter
\
CharacterEscape
\
ClassSetReservedPunctuator
令 cv 为本 ClassSetCharacter 的 CharacterValue 。
令 c 为字符值为 cv 的字符。
返回仅包含字符 c 的 CharSet 。
ClassSetCharacter
::
\b
返回仅包含字符 U+0008 (BACKSPACE) 的 CharSet 。
22.2.2.9.1 CharacterRange (A , B )
抽象操作 CharacterRange 接收参数 A (CharSet )和
B (CharSet ),返回 CharSet 。调用时执行如下步骤:
断言 :A 和 B 各自仅包含一个字符。
令 a 为 A 中的唯一字符。
令 b 为 B 中的唯一字符。
令 i 为字符 a 的字符值。
令 j 为字符 b 的字符值。
断言 :i ≤ j 。
返回包含所有字符值在 i 到 j (含)区间的字符的 CharSet 。
22.2.2.9.2 HasEitherUnicodeFlag (rer )
抽象操作 HasEitherUnicodeFlag 接收参数 rer (RegExp
Record ),返回布尔值。调用时执行如下步骤:
如果 rer .[[Unicode]] 为 true
或 rer .[[UnicodeSets]] 为
true ,则:
返回 true 。
返回 false 。
22.2.2.9.3 WordCharacters (rer )
抽象操作 WordCharacters 接收参数 rer (RegExp Record ),返回
CharSet 。返回正则表达式中
\b、\B、\w、\W 所认为的“单词字符”。调用时执行如下步骤:
令 basicWordChars 为包含所有 ASCII 单词字符 的
CharSet 。
令 extraWordChars 为包含所有字符 c 的 CharSet ,其中 c 不在
basicWordChars 内,但 Canonicalize (rer ,
c ) 在 basicWordChars 内。
断言 :除非
HasEitherUnicodeFlag (rer )
为 true 且 rer .[[IgnoreCase]] 为 true ,否则
extraWordChars 为空。
返回 basicWordChars 与 extraWordChars 的并集。
22.2.2.9.4 AllCharacters (rer )
抽象操作 AllCharacters 接收参数 rer (RegExp Record ),返回
CharSet 。根据正则表达式标志返回“所有字符”的集合。调用时执行如下步骤:
如果 rer .[[UnicodeSets]] 为
true 且 rer .[[IgnoreCase]]
为 true :
返回包含所有无 简单大小写折叠 映射(即
scf (c )=c )的
Unicode 码点 c 的 CharSet 。
否则若 HasEitherUnicodeFlag (rer )
为 true :
返回包含所有码点值的 CharSet 。
否则:
返回包含所有码元值的 CharSet 。
22.2.2.9.5 MaybeSimpleCaseFolding (rer ,
A )
抽象操作 MaybeSimpleCaseFolding 接收参数 rer (RegExp
Record )、A (CharSet ),返回 CharSet 。如果 rer .[[UnicodeSets]] 为 false 或 rer .[[IgnoreCase]] 为 false ,则返回 A 。否则,使用
Unicode Character Database 中 简单大小写折叠 (scf(cp ) )的定义,对
A 的每个 CharSetElement 的每个码点字符做映射,并返回结果
CharSet 。调用时执行如下步骤:
如果 rer .[[UnicodeSets]] 为
false 或 rer .[[IgnoreCase]] 为 false ,返回
A 。
令 B 为一个新的空 CharSet 。
对 A 的每一个 CharSetElement
s ,执行:
令 t 为空字符序列。
对 s 中每一个码点 cp ,执行:
将 scf (cp ) 附加到
t 。
将 t 添加到 B 。
返回 B 。
22.2.2.9.6 CharacterComplement (rer ,
S )
抽象操作 CharacterComplement 接收参数 rer (RegExp
Record )、S (CharSet ),返回 CharSet 。调用时执行如下步骤:
令 A = AllCharacters (rer )。
返回包含所有属于 A 但不属于 S 的 CharSetElements 的 CharSet 。
22.2.2.9.7 UnicodeMatchProperty (rer ,
p )
抽象操作 UnicodeMatchProperty 接收参数 rer (RegExp
Record )、p (ECMAScript 源文本 ),返回 Unicode
属性名 。调用时执行如下步骤:
如果 rer .[[UnicodeSets]] 为
true 且 p 是 表 71
“Property name” 列中的 Unicode 属性名,则:
返回 Unicode 码点 p 组成的 List 。
断言 :p 是 表 69 、“Property
name and aliases” 或 表 70
中的 Unicode 属性名或属性别名。
令 c 为该行 “Canonical property name” 列中给出的 p 的规范属性名。
返回 Unicode 码点 c 组成的 List 。
实现必须支持 表 69 、表 70 和 表 71 中列出的
Unicode 属性名和别名。为保证互操作性,实现不得支持其他属性名或别名。
注 1
例如,Script_Extensions(属性名 )和
scx(属性别名)有效,但 script_extensions 或 Scx 无效。
注 2
这些属性集合是 UTS18 RL1.2 要求的超集。
注 3
这些表中的拼写(包括大小写)与 Unicode Character Database 文件 PropertyAliases.txt
保持一致。该文件中的拼写是 保证稳定的 。
表 69:非二值(非布尔型)Unicode 属性别名及其规范属性名
表 70:二值(布尔型)Unicode 属性别名及其规范属性名
表 71:字符串的二值(布尔型)Unicode 属性
属性名
Basic_Emoji(基础表情符号)
Emoji_Keycap_Sequence(表情符号按键序列)
RGI_Emoji_Modifier_Sequence(RGI表情符号修饰符序列)
RGI_Emoji_Flag_Sequence(RGI表情符号旗帜序列)
RGI_Emoji_Tag_Sequence(RGI表情符号标签序列)
RGI_Emoji_ZWJ_Sequence(RGI表情符号ZWJ序列)
RGI_Emoji(RGI表情符号)
22.2.2.9.8 UnicodeMatchPropertyValue (p ,
v )
抽象操作 UnicodeMatchPropertyValue 接收参数 p (ECMAScript 源文本 )和
v (ECMAScript 源文本 ),返回一个 Unicode
属性值。调用时执行如下步骤:
断言 :p 是 表
69 “规范属性名”列中列出的规范、无别名的 Unicode 属性名 。
断言 :v 是 PropertyValueAliases.txt
中针对属性 p 列出的属性值或属性值别名。
令 value 为 v 的规范属性值,其值为对应行“规范属性值”列中给出的内容。
返回 Unicode 码点 value 组成的 List 。
实现必须支持 表 69 中属性对应的 PropertyValueAliases.txt
文件中列出的 Unicode 属性值和属性值别名。为保证互操作性,实现不得支持其他属性值或属性值别名。
注 1
例如,Xpeo 和 Old_Persian 是有效的
Script_Extensions 属性值,但 xpeo 和
Old Persian 无效。
注 2
此算法不同于 UAX44
中列出的符号值匹配规则 :不会忽略大小写、空白 、U+002D(连字符)和 U+005F(下划线),并且不支持
Is 前缀。
22.2.2.10 运行时语义:CompileClassSetString
语法定向操作
CompileClassSetString 接收参数 rer (RegExp
Record ),返回一个字符序列。该操作按以下产生式分段定义:
ClassString ::
[empty]
返回空的字符序列。
ClassString ::
NonEmptyClassString
返回 CompileClassSetString of
NonEmptyClassString ,参数为
rer 。
NonEmptyClassString
::
ClassSetCharacter
NonEmptyClassString
opt
令 cs 为 CompileToCharSet of ClassSetCharacter ,参数为
rer 。
令 s1 为 cs 的唯一 CharSetElement
的字符序列。
如果 NonEmptyClassString 存在,则:
令 s2 为 CompileClassSetString
of NonEmptyClassString ,参数为
rer 。
返回 s1 和 s2 的拼接。
返回 s1 。
22.2.3 正则表达式创建的抽象操作
22.2.3.1 RegExpCreate ( P , F )
抽象操作 RegExpCreate 接收参数 P (一个 ECMAScript 语言值 )和
F (字符串或 undefined ),返回 包含 对象的正常完成,或
抛出完成 。调用时执行如下步骤:
令 obj 为 ! RegExpAlloc (%RegExp% )。
返回 ? RegExpInitialize (obj ,
P , F )。
22.2.3.2 RegExpAlloc ( newTarget )
抽象操作 RegExpAlloc 接收参数 newTarget (构造函数 ),返回 包含 对象的正常完成,或
抛出完成 。调用时执行如下步骤:
令 obj 为 ? OrdinaryCreateFromConstructor (newTarget ,
"%RegExp.prototype%" , « [[OriginalSource]] , [[OriginalFlags]] , [[RegExpRecord]] , [[RegExpMatcher]]
»)。
执行 ! DefinePropertyOrThrow (obj ,
"lastIndex" , PropertyDescriptor { [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : false })。
返回 obj 。
22.2.3.3 RegExpInitialize ( obj , pattern ,
flags )
抽象操作 RegExpInitialize 接收参数 obj (对象)、pattern (ECMAScript
语言值 )、flags (ECMAScript
语言值 ),返回 包含 对象的正常完成,或
抛出完成 。调用时执行如下步骤:
如果 pattern 是 undefined ,令 P 为空字符串。
否则,令 P 为 ? ToString (pattern )。
如果 flags 是 undefined ,令 F 为空字符串。
否则,令 F 为 ? ToString (flags )。
如果 F 包含除
"d" 、"g" 、"i" 、"m" 、"s" 、"u" 、"v" 、"y"
以外的任何代码单元,或 F 中有任何代码单元出现多次,则抛出 SyntaxError 异常。
如果 F 包含 "i" ,令 i =
true ;否则 i = false 。
如果 F 包含 "m" ,令 m =
true ;否则 m = false 。
如果 F 包含 "s" ,令 s =
true ;否则 s = false 。
如果 F 包含 "u" ,令 u =
true ;否则 u = false 。
如果 F 包含 "v" ,令 v =
true ;否则 v = false 。
如果 u 为 true 或 v 为 true ,则
令 patternText = StringToCodePoints (P )。
否则:
令 patternText 为将 P 的每个 16 位元素按 Unicode BMP
码点解释的结果。不会对这些元素做 UTF-16 解码。
令 parseResult = ParsePattern (patternText ,
u , v )。
如果 parseResult 是一个非空的 List ,且包含
SyntaxError 对象,则抛出 SyntaxError 异常。
断言 :parseResult 是一个 Pattern 解析节点 。
设置 obj .[[OriginalSource]] = P 。
设置 obj .[[OriginalFlags]] = F 。
令 capturingGroupsCount = CountLeftCapturingParensWithin (parseResult )。
令 rer 为 RegExp Record { [[IgnoreCase]] : i , [[Multiline]] : m , [[DotAll]] : s , [[Unicode]] : u , [[UnicodeSets]] : v , [[CapturingGroupsCount]] : capturingGroupsCount }。
设置 obj .[[RegExpRecord]] = rer 。
设置 obj .[[RegExpMatcher]] = CompilePattern of
parseResult ,参数为 rer 。
执行 ? Set (obj ,
"lastIndex" , +0 𝔽 ,
true )。
返回 obj 。
22.2.3.4 静态语义:ParsePattern (patternText ,
u , v )
抽象操作 ParsePattern 接收参数
patternText (Unicode码点序列)、u (布尔值)、v (布尔值),返回一个 解析节点 ,或一个非空的 List (元素为
SyntaxError 对象)。
注
调用时执行如下步骤:
如果 v 为 true 且 u 为 true ,
令 parseResult 为包含一个或多个 SyntaxError 对象的
List 。
否则,如果 v 为 true ,
令 parseResult = ParseText (patternText ,
Pattern [+UnicodeMode,
+UnicodeSetsMode,
+NamedCaptureGroups] )。
否则,如果 u 为 true ,
令 parseResult = ParseText (patternText ,
Pattern [+UnicodeMode,
~UnicodeSetsMode,
+NamedCaptureGroups] )。
否则:
令 parseResult = ParseText (patternText ,
Pattern [~UnicodeMode,
~UnicodeSetsMode,
+NamedCaptureGroups] )。
返回 parseResult 。
22.2.4 RegExp 构造函数
RegExp 构造函数 :
即 %RegExp% 。
是 全局对象 的 "RegExp" 属性的初始值。
作为 构造函数 调用时,会创建并初始化一个新的 RegExp 对象。
当作普通函数而非 构造函数 调用时,返回一个新的 RegExp 对象,或者如果唯一参数本身就是 RegExp
对象,则返回该参数本身。
可以作为类定义的 extends 子句的值。子类 构造函数 如果要继承指定的 RegExp 行为,必须包含对 RegExp 构造函数 的
super 调用,以便用必要的内部插槽来创建并初始化子类实例。
22.2.4.1 RegExp ( pattern , flags )
该函数被调用时执行以下步骤:
令 patternIsRegExp 为 ? IsRegExp (pattern )。
如果 NewTarget 是 undefined ,则
令 newTarget 为 活动函数对象 。
如果 patternIsRegExp 是 true 且 flags 是
undefined ,则
令 patternConstructor 为 ? Get (pattern ,
"constructor" )。
如果 SameValue (newTarget ,
patternConstructor ) 为 true ,返回
pattern 。
否则,
令 newTarget 为 NewTarget。
如果 pattern 是一个对象 且 pattern 有 [[RegExpMatcher]] 内部插槽,则
令 P 为 pattern .[[OriginalSource]] 。
如果 flags 是 undefined ,令 F 为
pattern .[[OriginalFlags]] 。
否则,令 F 为 flags 。
否则如果 patternIsRegExp 是 true ,则
令 P 为 ? Get (pattern ,
"source" )。
如果 flags 是 undefined ,则
令 F 为 ? Get (pattern ,
"flags" )。
否则,
令 F 为 flags 。
否则,
令 P 为 pattern 。
令 F 为 flags 。
令 O 为 ? RegExpAlloc (newTarget )。
返回 ? RegExpInitialize (O ,
P , F )。
注
如果 pattern 是通过 StringLiteral
传递的,会在该字符串被本函数处理前进行常规的转义序列替换。如果 pattern 必须包含一个转义序列以便被本函数识别,则必须在 StringLiteral 内对所有
U+005C(反斜杠)码点进行转义,以防止它们在形成 StringLiteral 内容时被移除。
22.2.5 RegExp 构造函数的属性
RegExp 构造函数 :
22.2.5.1 RegExp.escape ( S )
该函数返回 S 的一个副本,其中正则表达式模式 中可能具有特殊含义的字符都被替换为等价的转义序列。
调用时执行以下步骤:
如果 S 不是字符串 ,抛出
TypeError 异常。
令 escaped 为空字符串。
令 cpList 为 StringToCodePoints (S )。
对于 cpList 中的每个码点 cp ,执行
如果 escaped 为空字符串,且 cp 匹配 十进制数字 或 ASCII 字母 ,
则
注:转义首位数字可保证输出对应的模式文本在 \0 字符转义或 十进制转义 (如 \1)后仍能匹配
S,不会被解释为前一转义序列的扩展。首位 ASCII 字母的转义同理,适用于 \c 后的情况。
令 numericValue 为 cp 的数值。
令 hex 为 Number::toString (𝔽 (numericValue ), 16)。
断言 :hex 长度为 2。
设置 escaped 为字符串拼接 0x005C(反斜杠)、"x" 及 hex 。
否则,
设置 escaped 为 escaped 与 EncodeForRegExpEscape (cp )
的字符串拼接。
返回 escaped 。
注
虽然名字相似,EscapeRegExpPattern 和
RegExp.escape 并不执行类似操作。前者用于将模式转义为字符串表示,后者用于将字符串转义为模式内部使用。
22.2.5.1.1 EncodeForRegExpEscape ( cp )
抽象操作 EncodeForRegExpEscape 接收参数 cp (码点),返回一个字符串。返回值即为匹配 cp 的模式
Pattern 。如 cp
为空白字符或 ASCII 标点,则返回转义序列。否则,返回 cp 本身的字符串表示。调用时执行如下步骤:
如果 cp 匹配 SyntaxCharacter 或等于
U+002F(/),则
返回 0x005C(反斜杠)与 UTF16EncodeCodePoint (cp )
的字符串拼接。
否则,如果 cp 在 表
67 的“Code Point”列中,则
返回 0x005C(反斜杠)与该行“ControlEscape”列字符串的字符串拼接。
令 otherPunctuators 为字符串 ",-=<>#&!%:;@~'`" 与 0x0022(引号)。
令 toEscape 为 StringToCodePoints (otherPunctuators )。
如果 toEscape 包含 cp ,或 cp 匹配 WhiteSpace 、LineTerminator ,或
cp 与 前导代理项 或尾随代理项 数值相同,则
令 cpNum 为 cp 的数值。
如果 cpNum ≤ 0xFF,则
令 hex 为 Number::toString (𝔽 (cpNum ), 16)。
返回 0x005C(反斜杠)、"x" 及 StringPad (hex ,
2, "0", start ) 的字符串拼接。
令 escaped 为空字符串。
令 codeUnits 为 UTF16EncodeCodePoint (cp )。
对于 codeUnits 中每个 code unit cu ,执行
设置 escaped 为 escaped 与 UnicodeEscape (cu )
的字符串拼接。
返回 escaped 。
返回 UTF16EncodeCodePoint (cp )。
22.2.5.2 RegExp.prototype
RegExp.prototype 的初始值为 RegExp 原型对象 。
该属性具有属性:{ [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false }。
22.2.5.3 get RegExp [ %Symbol.species% ]
RegExp[%Symbol.species%] 是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数调用时执行如下步骤:
返回 this 值。
此函数的 "name" 属性值为 "get [Symbol.species]" 。
注
RegExp 原型方法通常使用其 this 值的 构造函数 来创建派生对象。但子类 构造函数
可以通过重定义其 %Symbol.species% 属性来覆盖此默认行为。
22.2.6 RegExp 原型对象的属性
RegExp 原型对象 :
即 %RegExp.prototype% 。
是一个 普通对象 。
不是 RegExp 实例,不具有 [[RegExpMatcher]] 内部插槽,也没有 RegExp 实例对象的其他内部插槽。
拥有 [[Prototype]] 内部插槽,其值为 %Object.prototype% 。
注
RegExp 原型对象自身没有 "valueOf" 属性,但它从 Object 原型对象
继承了 "valueOf" 属性。
22.2.6.1 RegExp.prototype.constructor
RegExp.prototype.constructor 的初始值为 %RegExp% 。
22.2.6.2 RegExp.prototype.exec ( string )
该方法在 string 中搜索正则表达式的匹配项,并返回包含匹配结果的数组,若 string 不匹配则返回
null 。
调用时执行如下步骤:
令 R 为 this 值。
执行 ? RequireInternalSlot (R ,
[[RegExpMatcher]] )。
令 S 为 ? ToString (string )。
返回 ? RegExpBuiltinExec (R ,
S )。
22.2.6.3 get RegExp.prototype.dotAll
RegExp.prototype.dotAll 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0073(小写字母 s)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.4 get RegExp.prototype.flags
RegExp.prototype.flags 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
如果 R 不是对象 ,抛出 TypeError
异常。
令 codeUnits 为一个新的空 List 。
令 hasIndices 为 ToBoolean (? Get (R ,
"hasIndices" ))。
如果 hasIndices 为 true ,将码元 0x0064(小写字母 d)添加到
codeUnits 。
令 global 为 ToBoolean (? Get (R ,
"global" ))。
如果 global 为 true ,将码元 0x0067(g)添加到
codeUnits 。
令 ignoreCase 为 ToBoolean (? Get (R ,
"ignoreCase" ))。
如果 ignoreCase 为 true ,将码元 0x0069(i)添加到
codeUnits 。
令 multiline 为 ToBoolean (? Get (R ,
"multiline" ))。
如果 multiline 为 true ,将码元 0x006D(m)添加到
codeUnits 。
令 dotAll 为 ToBoolean (? Get (R ,
"dotAll" ))。
如果 dotAll 为 true ,将码元 0x0073(s)添加到
codeUnits 。
令 unicode 为 ToBoolean (? Get (R ,
"unicode" ))。
如果 unicode 为 true ,将码元 0x0075(u)添加到
codeUnits 。
令 unicodeSets 为 ToBoolean (? Get (R ,
"unicodeSets" ))。
如果 unicodeSets 为 true ,将码元 0x0076(v)添加到
codeUnits 。
令 sticky 为 ToBoolean (? Get (R ,
"sticky" ))。
如果 sticky 为 true ,将码元 0x0079(y)添加到
codeUnits 。
返回由 List
codeUnits 组成的字符串;若 codeUnits 为空,则返回空字符串。
22.2.6.4.1 RegExpHasFlag ( R , codeUnit
)
抽象操作 RegExpHasFlag 接收参数 R (ECMAScript
语言值 )和 codeUnit (码元),返回一个 包含 布尔值或
undefined 的正常完成,或 抛出完成 。调用时执行如下步骤:
如果 R 不是对象 ,抛出
TypeError 异常。
如果 R 没有 [[OriginalFlags]] 内部插槽,则
如果 SameValue (R ,
%RegExp.prototype% )
为 true ,返回 undefined 。
否则,抛出 TypeError 异常。
令 flags 为 R .[[OriginalFlags]] 。
如果 flags 包含 codeUnit ,返回 true 。
返回 false 。
22.2.6.5 get RegExp.prototype.global
RegExp.prototype.global 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0067(g)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.6 get RegExp.prototype.hasIndices
RegExp.prototype.hasIndices 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0064(d)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.7 get RegExp.prototype.ignoreCase
RegExp.prototype.ignoreCase 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0069(i)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.8 RegExp.prototype [ %Symbol.match% ] ( string
)
该方法调用时执行如下步骤:
令 rx 为 this 值。
如果 rx 不是对象 ,抛出 TypeError
异常。
令 S 为 ? ToString (string )。
令 flags 为 ? ToString (? Get (rx ,
"flags" ))。
如果 flags 不包含 "g" ,则
返回 ? RegExpExec (rx ,
S )。
否则,
如果 flags 包含 "u" 或 flags 包含
"v" ,令 fullUnicode 为
true 。否则,令 fullUnicode 为
false 。
执行 ? Set (rx ,
"lastIndex" , +0 𝔽 ,
true )。
令 A 为 ! ArrayCreate (0)。
令 n 为 0。
重复,
令 result 为 ? RegExpExec (rx ,
S )。
如果 result 为 null ,则
如果 n = 0,返回 null 。
返回 A 。
否则,
令 matchStr 为 ? ToString (?
Get (result ,
"0" ))。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )),
matchStr )。
如果 matchStr 是空字符串,则
令 thisIndex 为 ℝ (?
ToLength (?
Get (rx ,
"lastIndex" )))。
令 nextIndex 为 AdvanceStringIndex (S ,
thisIndex , fullUnicode )。
执行 ? Set (rx ,
"lastIndex" , 𝔽 (nextIndex ),
true )。
设置 n 为 n + 1。
该方法的 "name" 属性值为 "[Symbol.match]" 。
注
%Symbol.match% 属性被 IsRegExp
抽象操作用于识别具有正则表达式基本行为的对象。如果缺少 %Symbol.match%
属性,或该属性的值经布尔转换不是 true ,则表明该对象不应被当作正则表达式对象使用。
22.2.6.9 RegExp.prototype [ %Symbol.matchAll% ] (
string )
该方法调用时执行如下步骤:
令 R 为 this 值。
如果 R 不是对象 ,抛出 TypeError
异常。
令 S 为 ? ToString (string )。
令 C 为 ? SpeciesConstructor (R ,
%RegExp% )。
令 flags 为 ? ToString (? Get (R ,
"flags" ))。
令 matcher 为 ? Construct (C ,
« R ,
flags »)。
令 lastIndex 为 ? ToLength (? Get (R ,
"lastIndex" ))。
执行 ? Set (matcher ,
"lastIndex" , lastIndex , true )。
如果 flags 包含 "g" ,令 global 为
true 。
否则,令 global 为 false 。
如果 flags 包含 "u" 或 flags 包含
"v" ,令 fullUnicode 为 true 。
否则,令 fullUnicode 为 false 。
返回 CreateRegExpStringIterator (matcher ,
S , global , fullUnicode )。
该方法的 "name" 属性值为 "[Symbol.matchAll]" 。
22.2.6.10 get RegExp.prototype.multiline
RegExp.prototype.multiline 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x006D(m)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.11 RegExp.prototype [ %Symbol.replace% ] (
string , replaceValue )
该方法调用时执行如下步骤:
令 rx 为 this 值。
如果 rx 不是对象 ,抛出 TypeError
异常。
令 S 为 ? ToString (string )。
令 lengthS 为 S 的长度。
令 functionalReplace 为 IsCallable (replaceValue )。
如果 functionalReplace 为 false ,则
设置 replaceValue 为 ? ToString (replaceValue )。
令 flags 为 ? ToString (? Get (rx ,
"flags" ))。
如果 flags 包含 "g" ,令 global 为
true ;否则 global 为 false 。
如果 global 为 true ,则
执行 ? Set (rx ,
"lastIndex" , +0 𝔽 ,
true )。
令 results 为一个新的空 List 。
令 done 为 false 。
重复,直到 done 为 false ,
令 result 为 ? RegExpExec (rx ,
S )。
如果 result 为 null ,则
设置 done 为 true 。
否则,
将 result 添加到 results 。
如果 global 为 false ,则
设置 done 为 true 。
否则,
令 matchStr 为 ? ToString (?
Get (result ,
"0" ))。
如果 matchStr 是空字符串,则
令 thisIndex 为 ℝ (?
ToLength (?
Get (rx ,
"lastIndex" )))。
如果 flags 包含 "u" 或
flags 包含 "v" ,令
fullUnicode 为 true ;否则
fullUnicode 为 false 。
令 nextIndex 为 AdvanceStringIndex (S ,
thisIndex , fullUnicode )。
执行 ? Set (rx ,
"lastIndex" , 𝔽 (nextIndex ),
true )。
令 accumulatedResult 为空字符串。
令 nextSourcePosition 为 0。
对于 results 中的每个元素 result ,执行
令 resultLength 为 ? LengthOfArrayLike (result )。
令 nCaptures 为 max (resultLength - 1, 0)。
令 matched 为 ? ToString (?
Get (result ,
"0" ))。
令 matchLength 为 matched 的长度。
令 position 为 ? ToIntegerOrInfinity (? Get (result ,
"index" ))。
将 position 限制在 0 到 lengthS 之间。
令 captures 为一个新的空 List 。
令 n 为 1。
重复,直到 n ≤ nCaptures ,
令 capN 为 ? Get (result ,
! ToString (𝔽 (n )))。
如果 capN 不为 undefined ,则
设置 capN 为 ? ToString (capN )。
将 capN 添加到 captures 。
注:当 n = 1 时,上一步将第一个元素放入 captures (索引 0)。更一般地,第
n 个捕获组(第 n 对括号捕获的字符)在 captures [n - 1]。
设置 n 为 n + 1。
令 namedCaptures 为 ? Get (result ,
"groups" )。
如果 functionalReplace 为 true ,则
令 replacerArgs 为 « matched
»、captures 和 « 𝔽 (position ),
S » 的列表拼接。
如果 namedCaptures 不为 undefined ,则
将 namedCaptures 添加到 replacerArgs 。
令 replacementValue 为 ? Call (replaceValue ,
undefined , replacerArgs )。
令 replacementString 为 ? ToString (replacementValue )。
否则,
如果 namedCaptures 不为 undefined ,则
设置 namedCaptures 为 ? ToObject (namedCaptures )。
令 replacementString 为 ? GetSubstitution (matched ,
S , position , captures ,
namedCaptures , replaceValue )。
如果 position ≥ nextSourcePosition ,则
注:position 通常不会倒退。如果发生,说明是行为异常的 RegExp 子类或通过副作用改变了 global
标志或 rx 的其它特性,此时对应替换会被忽略。
设置 accumulatedResult 为
accumulatedResult 、S 的
nextSourcePosition 到 position 子串、和
replacementString 的字符串拼接。
设置 nextSourcePosition 为 position +
matchLength 。
如果 nextSourcePosition ≥ lengthS ,返回
accumulatedResult 。
返回 accumulatedResult 与 S 从 nextSourcePosition
开始的子串的字符串拼接。
该方法的 "name" 属性值为 "[Symbol.replace]" 。
22.2.6.12 RegExp.prototype [ %Symbol.search% ] (
string )
该方法调用时执行如下步骤:
令 rx 为 this 值。
如果 rx 不是对象 ,抛出 TypeError
异常。
令 S 为 ? ToString (string )。
令 previousLastIndex 为 ? Get (rx ,
"lastIndex" )。
如果 previousLastIndex 不为 +0 𝔽 ,则
执行 ? Set (rx ,
"lastIndex" , +0 𝔽 ,
true )。
令 result 为 ? RegExpExec (rx , S )。
令 currentLastIndex 为 ? Get (rx ,
"lastIndex" )。
如果 SameValue (currentLastIndex ,
previousLastIndex ) 为 false ,则
执行 ? Set (rx ,
"lastIndex" , previousLastIndex ,
true )。
如果 result 为 null ,返回
-1 𝔽 。
返回 ? Get (result ,
"index" )。
该方法的 "name" 属性值为 "[Symbol.search]" 。
注
本 RegExp 对象的 "lastIndex" 和 "global"
属性在执行搜索时会被忽略,并且 "lastIndex" 属性保持不变。
22.2.6.13 get RegExp.prototype.source
RegExp.prototype.source 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
如果 R 不是对象 ,抛出 TypeError
异常。
如果 R 没有 [[OriginalSource]] 内部插槽,则
如果 SameValue (R ,
%RegExp.prototype% )
为 true ,返回 "(?:)" 。
否则,抛出 TypeError 异常。
断言 :R 拥有 [[OriginalFlags]] 内部插槽。
令 src 为 R .[[OriginalSource]] 。
令 flags 为 R .[[OriginalFlags]] 。
返回 EscapeRegExpPattern (src ,
flags )。
22.2.6.13.1 EscapeRegExpPattern ( P , F
)
抽象操作 EscapeRegExpPattern 接收参数 P (字符串)和 F (字符串),返回一个字符串。调用时执行如下步骤:
如果 F 包含 "v" ,则
令 patternSymbol 为 Pattern [+UnicodeMode,
+UnicodeSetsMode] 。
否则如果 F 包含 "u" ,则
令 patternSymbol 为 Pattern [+UnicodeMode,
~UnicodeSetsMode] 。
否则:
令 patternSymbol 为 Pattern [~UnicodeMode,
~UnicodeSetsMode] 。
令 S 为形式为 patternSymbol 的字符串,其内容等价于将 P 按 UTF-16
编码的 Unicode 码点解释后得到的模式,并对部分码点按下述方式转义。S 可能与 P 相同,也可能不同;但对
S 作为 patternSymbol 求值所得的 抽象闭包 必须与构造对象的 [[RegExpMatcher]] 内部插槽给出的 抽象闭包 行为一致。对同一 P 和
F 多次调用本操作,结果必须一致。
pattern 中的 / 及所有 LineTerminator 码点须在
S 中转义,以确保 字符串拼接
"/" 、S 、"/" 和 F 可作为
RegularExpressionLiteral
被解析,并与构造的正则表达式行为一致。如 P 为 "/" ,则 S 可为
"\/" 或 "\u002F" ,但不能为
"/" ,否则 /// 后接 F 会被解析为 单行注释 而不是
正则表达式字面量 。若
P 为空字符串,则 S 可为 "(?:)" 。
返回 S 。
注
尽管名字类似,RegExp.escape 与 EscapeRegExpPattern
并不执行类似操作。前者用于将字符串转义为可在模式中使用的内容,后者用于将模式转义为可作为字符串表示。
22.2.6.14 RegExp.prototype [ %Symbol.split% ] (
string , limit )
注 1
该方法返回一个数组,数组中存储了将 string 转换为字符串后的子串。这些子串是通过从左到右搜索 this
值正则表达式的匹配项确定的;这些匹配项不属于返回数组中的任何字符串,而是将字符串拆分开。
this
值可以是空正则表达式,也可以是能够匹配空字符串的正则表达式。在这种情况下,正则表达式不会匹配输入字符串开头或结尾的空子串,也不会匹配前一个分隔符匹配末尾的空子串。(例如,如果正则表达式匹配空字符串,则字符串会被拆分为单个码元元素;结果数组长度等于字符串长度,每个子串只包含一个码元。)某个索引处只考虑第一次匹配,即使回溯能得到非空子串匹配也不会采纳。(例如,/a*?/[Symbol.split]("ab")
的结果是 ["a", "b"],而 /a*/[Symbol.split]("ab") 的结果是
["","b"]。)
如果 string 是(或转换为)空字符串,结果取决于正则表达式是否能匹配空字符串。如果能,结果数组无元素;否则,结果数组含一个元素,即空字符串。
如果正则表达式含有捕获括号,则每次 separator 匹配时,括号捕获的结果(包括
undefined )会被拼接进输出数组。例如,
/<(\/)?([^<> ]+)>/[Symbol.split]("A<B > bold</B > and<CODE > coded</CODE > ")
结果为数组
["A" , undefined , "B" , "bold" , "/" , "B" , "and" , undefined , "CODE" , "coded" , "/" , "CODE" , "" ]
如果 limit 不为 undefined ,则输出数组会被截断为不多于 limit
个元素。
该方法调用时执行如下步骤:
令 rx 为 this 值。
如果 rx 不是对象 ,抛出 TypeError
异常。
令 S 为 ? ToString (string )。
令 C 为 ? SpeciesConstructor (rx ,
%RegExp% )。
令 flags 为 ? ToString (? Get (rx ,
"flags" ))。
如果 flags 包含 "u" 或 flags 包含
"v" ,令 unicodeMatching 为 true 。
否则,令 unicodeMatching 为 false 。
如果 flags 包含 "y" ,令 newFlags 为
flags 。
否则,令 newFlags 为 flags 与 "y" 的字符串拼接。
令 splitter 为 ? Construct (C ,
« rx ,
newFlags »)。
令 A 为 ! ArrayCreate (0)。
令 lengthA 为 0。
如果 limit 是 undefined ,令 lim 为 232
- 1;否则,令 lim 为 ℝ (? ToUint32 (limit ))。
如果 lim = 0,返回 A 。
如果 S 是空字符串,则
令 z 为 ? RegExpExec (splitter ,
S )。
如果 z 不为 null ,返回 A 。
执行 ! CreateDataPropertyOrThrow (A ,
"0" , S )。
返回 A 。
令 size 为 S 的长度。
令 p 为 0。
令 q 为 p 。
重复,直到 q < size ,
执行 ? Set (splitter ,
"lastIndex" , 𝔽 (q ),
true )。
令 z 为 ? RegExpExec (splitter ,
S )。
如果 z 为 null ,则
设置 q 为 AdvanceStringIndex (S ,
q , unicodeMatching )。
否则,
令 e 为 ℝ (? ToLength (? Get (splitter ,
"lastIndex" )))。
将 e 限制为不大于 size 。
如果 e = p ,则
设置 q 为 AdvanceStringIndex (S ,
q , unicodeMatching )。
否则,
令 T 为 substring of
S 从 p 到 q 。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (lengthA )),
T )。
设置 lengthA 为 lengthA + 1。
如果 lengthA = lim ,返回 A 。
设置 p 为 e 。
令 numberOfCaptures 为 ? LengthOfArrayLike (z )。
将 numberOfCaptures 限制为
numberOfCaptures - 1 与 0 之间的最大值。
令 i 为 1。
重复,直到 i ≤ numberOfCaptures ,
令 nextCapture 为 ? Get (z ,
! ToString (𝔽 (i )))。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (lengthA )),
nextCapture )。
设置 i 为 i + 1。
设置 lengthA 为 lengthA + 1。
如果 lengthA = lim ,返回
A 。
设置 q 为 p 。
令 T 为 substring of S 从 p 到
size 。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (lengthA )),
T )。
返回 A 。
该方法的 "name" 属性值为 "[Symbol.split]" 。
注 2
该方法会忽略本 RegExp 对象的 "global" 和 "sticky" 属性值。
22.2.6.15 get RegExp.prototype.sticky
RegExp.prototype.sticky 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0079(y)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.16 RegExp.prototype.test ( S )
该方法调用时执行如下步骤:
令 R 为 this 值。
如果 R 不是对象 ,抛出 TypeError
异常。
令 string 为 ? ToString (S )。
令 match 为 ? RegExpExec (R ,
string )。
如果 match 不为 null ,返回 true ;否则返回
false 。
22.2.6.17 RegExp.prototype.toString ( )
令 R 为 this 值。
如果 R 不是对象 ,抛出 TypeError
异常。
令 pattern 为 ? ToString (? Get (R ,
"source" ))。
令 flags 为 ? ToString (? Get (R ,
"flags" ))。
令 result 为 字符串拼接
"/" 、pattern 、"/" 和 flags 。
返回 result 。
注
返回的字符串具有 RegularExpressionLiteral
的形式,求值后是另一个行为与本对象一致的 RegExp 对象。
22.2.6.18 get RegExp.prototype.unicode
RegExp.prototype.unicode 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0075(u)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.6.19 get RegExp.prototype.unicodeSets
RegExp.prototype.unicodeSets 是一个 访问器属性 ,其 set 访问器函数为
undefined 。get 访问器函数调用时执行如下步骤:
令 R 为 this 值。
令 cu 为码元 0x0076(v)。
返回 ? RegExpHasFlag (R ,
cu )。
22.2.7 正则匹配的抽象操作
22.2.7.1 RegExpExec ( R , S )
抽象操作 RegExpExec 接收参数 R (对象)和 S (字符串),返回 包含 对象或
null 的正常完成,或 抛出完成 。调用时执行如下步骤:
令 exec 为 ? Get (R ,
"exec" )。
如果 IsCallable (exec ) 为
true ,则
令 result 为 ? Call (exec ,
R , « S »)。
如果 result 不是对象 且 result 不是
null ,抛出 TypeError 异常。
返回 result 。
执行 ? RequireInternalSlot (R ,
[[RegExpMatcher]] )。
返回 ? RegExpBuiltinExec (R ,
S )。
注
如果未找到可调用的 "exec"
属性,本算法会退回内建正则匹配算法。这为针对早期版本编写的代码提供了兼容行为,此前大多数使用正则表达式的内建算法不会动态查找
"exec" 属性。
22.2.7.2 RegExpBuiltinExec ( R , S )
抽象操作 RegExpBuiltinExec 接收参数 R (初始化后的 RegExp 实例)和 S (字符串),返回 包含 一个 数组异类对象 或 null 的正常完成,或
抛出完成 。调用时执行如下步骤:
令 length 为 S 的长度。
令 lastIndex 为 ℝ (? ToLength (? Get (R ,
"lastIndex" )))。
令 flags 为 R .[[OriginalFlags]] 。
如果 flags 包含 "g" ,令 global 为
true ;否则为 false 。
如果 flags 包含 "y" ,令 sticky 为
true ;否则为 false 。
如果 flags 包含 "d" ,令 hasIndices 为
true ;否则为 false 。
如果 global 为 false 且 sticky 为
false ,将 lastIndex 设为 0。
令 matcher 为 R .[[RegExpMatcher]] 。
如果 flags 包含 "u" 或 flags 包含
"v" ,令 fullUnicode 为 true ;否则为
false 。
令 matchSucceeded 为 false 。
如果 fullUnicode 为 true ,令 input 为 StringToCodePoints (S );否则,令
input 为包含 S 各码元的 List 。
注:input 的每个元素都被视为一个字符。
重复,直到 matchSucceeded 为 false ,
如果 lastIndex > length ,则
如果 global 或 sticky 为 true ,则
执行 ? Set (R ,
"lastIndex" ,
+0 𝔽 ,
true )。
返回 null 。
令 inputIndex 为 S 索引 lastIndex 处对应
input 的下标。
令 r 为 matcher (input ,
inputIndex )。
如果 r 为 failure ,则
如果 sticky 为 true ,则
执行 ? Set (R ,
"lastIndex" ,
+0 𝔽 ,
true )。
返回 null 。
将 lastIndex 设为 AdvanceStringIndex (S ,
lastIndex , fullUnicode )。
否则,
断言 :r 是 MatchState 。
设置 matchSucceeded 为 true 。
令 e 为 r .[[EndIndex]] 。
如果 fullUnicode 为 true ,则将 e 设为 GetStringIndex (S ,
e )。
如果 global 或 sticky 为 true ,则
执行 ? Set (R ,
"lastIndex" , 𝔽 (e ),
true )。
令 n 为 r .[[Captures]] 的元素数。
断言 :n = R .[[RegExpRecord]] .[[CapturingGroupsCount]] 。
断言 :n < 232 - 1。
令 A 为 ! ArrayCreate (n + 1)。
断言 :A 的 "length"
数学值为 n + 1。
执行 ! CreateDataPropertyOrThrow (A ,
"index" , 𝔽 (lastIndex ))。
执行 ! CreateDataPropertyOrThrow (A ,
"input" , S )。
令 match 为 Match Record { [[StartIndex]] : lastIndex , [[EndIndex]] : e }。
令 indices 为一个新的空 List 。
令 groupNames 为一个新的空 List 。
将 match 添加到 indices 。
令 matchedSubstr 为 GetMatchString (S ,
match )。
执行 ! CreateDataPropertyOrThrow (A ,
"0" , matchedSubstr )。
如果 R 包含 GroupName ,
令 groups 为 OrdinaryObjectCreate (null )。
令 hasGroups 为 true 。
否则,
令 groups 为 undefined 。
令 hasGroups 为 false 。
执行 ! CreateDataPropertyOrThrow (A ,
"groups" , groups )。
令 matchedGroupNames 为一个新的空 List 。
对于所有 1 ≤ i ≤ n 的整数 i ,升序执行
令 captureI 为 r .[[Captures]]
的第 i 个元素。
如果 captureI 为 undefined ,
令 capturedValue 为 undefined 。
将 undefined 添加到 indices 。
否则,
令 captureStart 为 captureI .[[StartIndex]] 。
令 captureEnd 为 captureI .[[EndIndex]] 。
如果 fullUnicode 为 true ,
设置 captureStart 为 GetStringIndex (S ,
captureStart )。
设置 captureEnd 为 GetStringIndex (S ,
captureEnd )。
令 capture 为 Match
Record { [[StartIndex]] : captureStart ,
[[EndIndex]] : captureEnd }。
令 capturedValue 为 GetMatchString (S ,
capture )。
将 capture 添加到 indices 。
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (i )),
capturedValue )。
如果 R 的第 i 个捕获带有 GroupName ,
令 s 为该 GroupName 的 CapturingGroupName 。
如果 matchedGroupNames 包含 s ,
断言 :capturedValue
为 undefined 。
将 undefined 添加到 groupNames 。
否则,
如果 capturedValue 不为
undefined ,将 s 添加到
matchedGroupNames 。
注:如有多个同名分组,groups 可能已有属性 s 。但因 groups
是普通对象,其属性均为可写数据属性,CreateDataPropertyOrThrow 调用必然成功。
执行 ! CreateDataPropertyOrThrow (groups ,
s , capturedValue )。
将 s 添加到 groupNames 。
否则,
将 undefined 添加到 groupNames 。
如果 hasIndices 为 true ,
令 indicesArray 为 MakeMatchIndicesIndexPairArray (S ,
indices , groupNames , hasGroups )。
执行 ! CreateDataPropertyOrThrow (A ,
"indices" , indicesArray )。
返回 A 。
22.2.7.3 AdvanceStringIndex ( S , index ,
unicode )
抽象操作 AdvanceStringIndex 接收参数
S (字符串)、index (非负整数)、unicode (布尔值),返回一个整数。调用时执行如下步骤:
断言 :index ≤ 253 - 1。
如果 unicode 为 false ,返回 index + 1。
令 length 为 S 的长度。
如果 index + 1 ≥ length ,返回 index + 1。
令 cp 为 CodePointAt (S ,
index )。
返回 index + cp .[[CodeUnitCount]] 。
22.2.7.4 GetStringIndex ( S ,
codePointIndex )
抽象操作 GetStringIndex 接收参数 S (字符串)和 codePointIndex (非负整数),返回一个非负整数。它将
S 作为 UTF-16 编码码点序列,根据 6.1.4 ,返回与码点索引
codePointIndex 对应的码元索引,若不存在则返回 S 的长度。调用时执行如下步骤:
如果 S 是空字符串,返回 0。
令 len 为 S 的长度。
令 codeUnitCount 为 0。
令 codePointCount 为 0。
重复,直到 codeUnitCount < len ,
如果 codePointCount = codePointIndex ,返回
codeUnitCount 。
令 cp 为 CodePointAt (S ,
codeUnitCount )。
设置 codeUnitCount 为 codeUnitCount + cp .[[CodeUnitCount]] 。
设置 codePointCount 为 codePointCount + 1。
返回 len 。
22.2.7.5 匹配记录(Match Records)
匹配记录(Match Record) 是一种 Record
值,用于封装正则匹配或捕获的起止索引。
匹配记录的字段列于 表
72 。
表 72:Match Record 字段
字段名
值
含义
[[StartIndex]]
非负 整数
匹配开始(包含)的字符串起始码元数。
[[EndIndex]]
一个 整数 ,且 ≥ [[StartIndex]]
匹配结束(不含)的字符串起始码元数。
22.2.7.6 GetMatchString ( S , match )
抽象操作 GetMatchString 接收参数 S (字符串)和 match (Match
Record ),返回一个字符串。调用时执行如下步骤:
断言 :match .[[StartIndex]] ≤ match .[[EndIndex]] ≤ S 的长度。
返回 S 从 match .[[StartIndex]] 到
match .[[EndIndex]] 的 子串 。
22.2.7.7 GetMatchIndexPair ( S , match )
抽象操作 GetMatchIndexPair 接收参数 S (字符串)和 match (Match
Record ),返回一个数组。调用时执行如下步骤:
断言 :match .[[StartIndex]] ≤ match .[[EndIndex]] ≤ S 的长度。
返回 CreateArrayFromList («𝔽 (match .[[StartIndex]] ), 𝔽 (match .[[EndIndex]] )»)。
22.2.7.8 MakeMatchIndicesIndexPairArray ( S ,
indices , groupNames , hasGroups )
抽象操作 MakeMatchIndicesIndexPairArray 接收参数 S (字符串)、indices (List ,元素为 Match
Records 或
undefined )、groupNames (List ,元素为字符串或
undefined )、hasGroups (布尔值),返回一个数组。调用时执行如下步骤:
令 n 为 indices 的元素数。
断言 :n < 232 - 1。
断言 :groupNames 有 n - 1
个元素。
注:groupNames 列表中的元素与 indices 列表自 indices [1] 起一一对应。
令 A 为 ! ArrayCreate (n )。
如果 hasGroups 为 true ,
令 groups 为 OrdinaryObjectCreate (null )。
否则,
令 groups 为 undefined 。
执行 ! CreateDataPropertyOrThrow (A ,
"groups" , groups )。
对于 0 ≤ i < n 的每个整数 i ,升序执行
令 matchIndices 为 indices [i ]。
如果 matchIndices 不为 undefined ,
令 matchIndexPair 为 GetMatchIndexPair (S ,
matchIndices )。
否则,
令 matchIndexPair 为 undefined 。
执行 ! CreateDataPropertyOrThrow (A ,
!ToString (𝔽 (i )),
matchIndexPair )。
如果 i > 0,
令 s 为 groupNames [i - 1]。
如果 s 不为 undefined ,
断言 :groups
不为 undefined 。
注:如有多个同名分组,groups 可能已经有 s 属性。因 groups
是普通对象,属性均为可写数据属性,CreateDataPropertyOrThrow 调用必然成功。
执行 ! CreateDataPropertyOrThrow (groups ,
s , matchIndexPair )。
返回 A 。
22.2.8 RegExp 实例的属性
RegExp 实例是 普通对象 ,继承自 RegExp 原型对象 。RegExp
实例具有内部插槽 [[OriginalSource]] 、[[OriginalFlags]] 、[[RegExpRecord]] 和 [[RegExpMatcher]] 。[[RegExpMatcher]] 插槽的值是该正则对象
模式 的 抽象闭包 表示。
注
在 ECMAScript 2015 之前,RegExp 实例被规范为拥有自身的数据属性 data properties
"source" 、"global" 、"ignoreCase"
和 "multiline" 。这些属性现在被规范为 RegExp.prototype 的 访问器属性 。
RegExp 实例还具有以下属性:
22.2.8.1 lastIndex
"lastIndex" 属性的值指定下次匹配时从字符串的哪个索引开始。使用时会被强制转换为 整数类型
Number (参见 22.2.7.2 )。该属性具有属性 { [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : false }。
22.2.9 RegExp 字符串迭代器对象
RegExp 字符串迭代器 是用于表示对某个特定字符串实例对象、针对某个特定 RegExp 实例对象进行迭代的对象。RegExp
字符串迭代器对象没有具名的 构造函数 ,而是通过调用某些 RegExp 实例对象的方法创建的。
22.2.9.1 CreateRegExpStringIterator ( R ,
S , global , fullUnicode )
抽象操作 CreateRegExpStringIterator 接收参数
R (对象)、S (字符串)、global (布尔值)、fullUnicode (布尔值),返回一个对象。调用时执行如下步骤:
令 iterator 为 OrdinaryObjectCreate (%RegExpStringIteratorPrototype% ,
« [[IteratingRegExp]] , [[IteratedString]] , [[Global]] ,
[[Unicode]] , [[Done]] »)。
设置 iterator .[[IteratingRegExp]] = R 。
设置 iterator .[[IteratedString]] = S 。
设置 iterator .[[Global]] = global 。
设置 iterator .[[Unicode]] =
fullUnicode 。
设置 iterator .[[Done]] = false 。
返回 iterator 。
22.2.9.2 %RegExpStringIteratorPrototype% 对象
%RegExpStringIteratorPrototype% 对象:
22.2.9.2.1 %RegExpStringIteratorPrototype%.next ( )
令 O 为 this 值。
如果 O 不是对象 ,抛出
TypeError 异常。
如果 O 不具有 RegExp
字符串迭代器 对象实例的所有内部插槽(见 22.2.9.3 ),抛出
TypeError 异常。
如果 O .[[Done]] 为 true ,
返回 CreateIteratorResultObject (undefined ,
true )。
令 R = O .[[IteratingRegExp]] 。
令 S = O .[[IteratedString]] 。
令 global = O .[[Global]] 。
令 fullUnicode = O .[[Unicode]] 。
令 match 为 ? RegExpExec (R ,
S )。
如果 match 为 null ,
设置 O .[[Done]] =
true 。
返回 CreateIteratorResultObject (undefined ,
true )。
如果 global 为 false ,
设置 O .[[Done]] =
true 。
返回 CreateIteratorResultObject (match ,
false )。
令 matchStr 为 ? ToString (?
Get (match ,
"0" ))。
如果 matchStr 是空字符串,
令 thisIndex 为 ℝ (? ToLength (? Get (R ,
"lastIndex" )))。
令 nextIndex 为 AdvanceStringIndex (S ,
thisIndex , fullUnicode )。
执行 ? Set (R ,
"lastIndex" , 𝔽 (nextIndex ),
true )。
返回 CreateIteratorResultObject (match ,
false )。
22.2.9.2.2 %RegExpStringIteratorPrototype% [
%Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值是字符串
"RegExp String Iterator" 。
该属性具有属性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : true }。
22.2.9.3 RegExp 字符串迭代器实例的属性
RegExp 字符串迭代器
实例是 普通对象 ,继承自 %RegExpStringIteratorPrototype%
内置对象。RegExp 字符串迭代器
实例初始时拥有 表 73 所列的内部插槽。
表 73:RegExp
字符串迭代器 实例的内部插槽
内部插槽
类型
描述
[[IteratingRegExp]]
对象
用于迭代的正则表达式。IsRegExp ([[IteratingRegExp]] ) 初始为
true 。
[[IteratedString]]
字符串
被迭代的字符串值。
[[Global]]
布尔值
指示 [[IteratingRegExp]] 是否为全局。
[[Unicode]]
布尔值
指示 [[IteratingRegExp]] 是否为 Unicode 模式。
[[Done]]
布尔值
指示迭代是否已完成。
23 索引集合
23.1 数组对象
数组是特殊对象 ,对某类属性名进行了特殊处理。关于此特殊处理的定义,见10.4.2 。
23.1.1 Array 构造函数
Array 构造函数 :
即 %Array% 。
是全局对象 的 "Array" 属性的初始值。
作为构造函数 调用时,会创建并初始化一个新的数组。
作为普通函数而不是构造函数 调用时,也会创建并初始化一个新的数组。因此,函数调用
Array(…) 等价于使用相同参数的对象创建表达式 new Array(…)。
是一个其行为根据参数数量和类型而异的函数。
可用作类定义中 extends 子句的值。打算继承数组特殊行为的子类构造函数 ,必须包含对 Array 构造函数 的
super 调用,以初始化作为数组特殊对象 的子类实例。然而,大多数
Array.prototype 方法是泛型方法,不依赖于其 this 值为数组特殊对象 。
23.1.1.1 Array ( ...values )
当调用该函数时,执行以下步骤:
如果 NewTarget 为 undefined ,则令 newTarget 为活动函数对象 ;否则令
newTarget 为 NewTarget。
令 proto 为 ? GetPrototypeFromConstructor (newTarget ,
"%Array.prototype%" )。
令 numberOfArgs 为 values 中元素的数量。
如果 numberOfArgs = 0,则
返回 ! ArrayCreate (0,
proto )。
否则如果 numberOfArgs = 1,则
令 len 为 values [0]。
令 array 为 ! ArrayCreate (0,
proto )。
如果 len 不是数字类型 ,则
执行 ! CreateDataPropertyOrThrow (array ,
"0" , len )。
令 intLen 为 1 𝔽 。
否则,
令 intLen 为 ! ToUint32 (len )。
如果 SameValueZero (intLen ,
len ) 为 false ,则抛出
RangeError 异常。
执行 ! Set (array ,
"length" , intLen , true )。
返回 array 。
否则,
断言 :numberOfArgs ≥ 2。
令 array 为 ? ArrayCreate (numberOfArgs ,
proto )。
令 k 为 0。
重复,直到 k < numberOfArgs ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 itemK 为 values [k ]。
执行 ! CreateDataPropertyOrThrow (array ,
Pk , itemK )。
令 k 为 k + 1。
断言 :array 的
"length" 属性的数学值为 numberOfArgs 。
返回 array 。
23.1.2 Array 构造函数的属性
Array 构造函数 :
23.1.2.1 Array.from ( items [ , mapper [ ,
thisArg ] ] )
当调用该方法时,执行以下步骤:
令 C 为 this 值。
如果 mapper 为 undefined ,则
令 mapping 为 false 。
否则,
如果 IsCallable (mapper )
为 false ,则抛出 TypeError 异常。
令 mapping 为 true 。
令 usingIterator 为 ? GetMethod (items , %Symbol.iterator% )。
如果 usingIterator 不为 undefined ,则
如果 IsConstructor (C )
为 true ,则
令 A 为 ? Construct (C )。
否则,
令 A 为 ! ArrayCreate (0)。
令 iteratorRecord 为 ? GetIteratorFromMethod (items ,
usingIterator )。
令 k 为 0。
重复,
如果 k ≥ 253 - 1,则
令 error 为 ThrowCompletion (新建的
TypeError 对象)。
返回 ? IteratorClose (iteratorRecord ,
error )。
令 Pk 为 ! ToString (𝔽 (k ))。
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 为 done ,则
执行 ? Set (A ,
"length" , 𝔽 (k ),
true )。
返回 A 。
如果 mapping 为 true ,则
令 mappedValue 为 Completion (Call (mapper ,
thisArg , « next , 𝔽 (k ) »))。
IfAbruptCloseIterator (mappedValue ,
iteratorRecord )。
否则,
令 mappedValue 为 next 。
令 defineStatus 为 Completion (CreateDataPropertyOrThrow (A ,
Pk , mappedValue ))。
IfAbruptCloseIterator (defineStatus ,
iteratorRecord )。
令 k 为 k + 1。
注:items 不是可迭代对象 ,因此假定其为类数组对象 。
令 arrayLike 为 ! ToObject (items )。
令 len 为 ? LengthOfArrayLike (arrayLike )。
如果 IsConstructor (C ) 为
true ,则
令 A 为 ? Construct (C , «
𝔽 (len ) »)。
否则,
令 A 为 ? ArrayCreate (len )。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ? Get (arrayLike ,
Pk )。
如果 mapping 为 true ,则
令 mappedValue 为 ? Call (mapper ,
thisArg , « kValue , 𝔽 (k )
»)。
否则,
令 mappedValue 为 kValue 。
执行 ? CreateDataPropertyOrThrow (A ,
Pk , mappedValue )。
令 k 为 k + 1。
执行 ? Set (A ,
"length" , 𝔽 (len ), true )。
返回 A 。
注
该方法是有意设计为泛型工厂方法;它不要求其 this 值为 Array 构造函数 。因此它可以被转移或继承到其它可用单一数字参数调用的构造函数 。
23.1.2.2 Array.isArray ( arg )
当调用该函数时,执行以下步骤:
返回 ? IsArray (arg )。
23.1.2.3 Array.of ( ...items )
当调用该方法时,执行以下步骤:
令 len 为 items 中元素的数量。
令 lenNumber 为 𝔽 (len )。
令 C 为 this 值。
如果 IsConstructor (C ) 为
true ,则
令 A 为 ? Construct (C , «
lenNumber »)。
否则,
令 A 为 ? ArrayCreate (len )。
令 k 为 0。
重复,直到 k < len ,
令 kValue 为 items [k ]。
令 Pk 为 ! ToString (𝔽 (k ))。
执行 ? CreateDataPropertyOrThrow (A ,
Pk , kValue )。
令 k 为 k + 1。
执行 ? Set (A ,
"length" , lenNumber , true )。
返回 A 。
注
该方法是有意设计为泛型工厂方法;它不要求其 this 值为 Array 构造函数 。因此它可以被转移或继承到其它可用单一数字参数调用的构造函数 。
23.1.2.4 Array.prototype
Array.prototype 的值为数组原型对象 。
该属性具有属性 { [[Writable]] : false , [[Enumerable]] : false , [[Configurable]] : false }。
23.1.2.5 get Array [ %Symbol.species% ]
Array[%Symbol.species%] 是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
返回 this 值。
该函数的 "name" 属性值为 "get [Symbol.species]" 。
注
数组原型方法通常使用其 this 值的 constructor
来创建派生对象。然而,子类构造函数 可以通过重写其 %Symbol.species% 属性来覆盖默认行为。
23.1.3 数组原型对象的属性
数组原型对象 :
即 %Array.prototype% 。
是数组特殊对象 ,并具有该类对象指定的内部方法。
具有一个 "length" 属性,其初始值为+0 𝔽 ,属性特性为 { [[Writable]] : true , [[Enumerable]] : false , [[Configurable]] : false }。
具有一个名为 [[Prototype]] 的内部槽,其值为 %Object.prototype% 。
注
数组原型对象被指定为数组特殊对象 ,以确保与 ECMAScript 2015 规范之前编写的
ECMAScript 代码兼容。
23.1.3.1 Array.prototype.at ( index )
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeIndex 为 ? ToIntegerOrInfinity (index )。
如果 relativeIndex ≥ 0,则
令 k 为 relativeIndex 。
否则,
令 k 为 len + relativeIndex 。
如果 k < 0 或 k ≥ len ,返回
undefined 。
返回 ? Get (O , ! ToString (𝔽 (k )))。
23.1.3.2 Array.prototype.concat ( ...items )
该方法返回一个数组,包含该对象的数组元素后跟每个参数的数组元素。
调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 A 为 ? ArraySpeciesCreate (O , 0)。
令 n 为 0。
将 O 前置到 items 。
对 items 的每个元素 E ,执行
令 spreadable 为 ? IsConcatSpreadable (E )。
如果 spreadable 为 true ,则
令 len 为 ? LengthOfArrayLike (E )。
如果 n + len > 253 - 1,抛出
TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 exists 为 ? HasProperty (E ,
Pk )。
如果 exists 为 true ,则
令 subElement 为 ? Get (E ,
Pk )。
执行 ? CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )),
subElement )。
令 n 为 n + 1。
令 k 为 k + 1。
否则,
注:E 作为单项加入而不是展开。
如果 n ≥ 253 - 1,抛出
TypeError 异常。
执行 ? CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )), E )。
令 n 为 n + 1。
执行 ? Set (A ,
"length" , 𝔽 (n ), true )。
返回 A 。
该方法的 "length" 属性为 1 𝔽 。
注 1
在步骤 6 中显式设置
"length" 属性,是为了确保当 items 的最后一个非空元素有尾部空洞或 A
不是内建数组时长度正确。
注 2
该方法被设计为泛型;不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.2.1 IsConcatSpreadable ( O )
抽象操作 IsConcatSpreadable 接收参数 O (一个 ECMAScript 语言值 ),并返回
包含 布尔值的正常完成,或
抛出完成 。调用时执行以下步骤:
如果 O 不是对象 ,返回
false 。
令 spreadable 为 ? Get (O ,
%Symbol.isConcatSpreadable% )。
如果 spreadable 不为 undefined ,返回 ToBoolean (spreadable )。
返回 ? IsArray (O )。
23.1.3.3 Array.prototype.constructor
Array.prototype.constructor 的初始值为 %Array% 。
23.1.3.4 Array.prototype.copyWithin ( target ,
start [ , end ] )
注 1
end 参数是可选的。如果未提供,则使用 this 值的长度。
注 2
如果 target 为负数,则视为 length +
target ,其中 length 是数组的长度。如果 start
为负数,则视为 length + start 。如果
end 为负数,则视为 length +
end 。
调用该方法时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeTarget 为 ? ToIntegerOrInfinity (target )。
如果 relativeTarget = -∞,令 to 为 0。
否则如果 relativeTarget < 0,令 to 为 max (len +
relativeTarget , 0)。
否则,令 to 为 min (relativeTarget ,
len )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 from 为 0。
否则如果 relativeStart < 0,令 from 为 max (len +
relativeStart , 0)。
否则,令 from 为 min (relativeStart ,
len )。
如果 end 为 undefined ,令 relativeEnd 为
len ;否则令 relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 final 为 0。
否则如果 relativeEnd < 0,令 final 为 max (len +
relativeEnd , 0)。
否则,令 final 为 min (relativeEnd , len )。
令 count 为 min (final - from ,
len - to )。
如果 from < to 且 to < from +
count ,则
令 direction 为 -1。
设置 from 为 from + count - 1。
设置 to 为 to + count - 1。
否则,
令 direction 为 1。
重复,直到 count > 0,
令 fromKey 为 ! ToString (𝔽 (from ))。
令 toKey 为 ! ToString (𝔽 (to ))。
令 fromPresent 为 ? HasProperty (O ,
fromKey )。
如果 fromPresent 为 true ,则
令 fromValue 为 ? Get (O ,
fromKey )。
执行 ? Set (O ,
toKey , fromValue , true )。
否则,
断言 :fromPresent
为 false 。
执行 ? DeletePropertyOrThrow (O ,
toKey )。
设置 from 为 from + direction 。
设置 to 为 to + direction 。
设置 count 为 count - 1。
返回 O 。
注 3
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.5 Array.prototype.entries ( )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
返回 CreateArrayIterator (O ,
key+value )。
23.1.3.6 Array.prototype.every ( callback [ ,
thisArg ] )
注 1
callback 应该是一个接受三个参数并返回可转换为布尔值的函数。every 会按升序对数组中实际存在的每个元素调用
callback 一次,直到遇到一个 callback 返回 false
的元素。如果找到这样的元素,every 会立即返回
false 。否则,every 返回
true 。callback 只会对数组中实际存在的元素调用,不会对数组中缺失的元素调用。
如果提供了 thisArg 参数,则每次调用 callback 时都会用作 this
值。如果未提供,则使用 undefined 。
callback 被调用时有三个参数:元素的值、元素的索引、被遍历的对象。
every 不会直接修改它所调用的对象,但该对象可能会被 callback 的调用修改。
every 处理的元素范围在第一次调用 callback 前就已确定。调用 every
之后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被修改,则传递给 callback 的值是在
every 访问该元素时的值;在 every
调用开始后被删除且尚未被访问的元素不会被访问。every 的行为类似于数学中的“全称量词”。特别地,对于空数组,它返回
true 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
令 testResult 为 ToBoolean (? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »))。
如果 testResult 为 false ,返回
false 。
设置 k 为 k + 1。
返回 true 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.7 Array.prototype.fill ( value [ ,
start [ , end ] ] )
注 1
start 参数是可选的。如果未提供,则使用 +0 𝔽 。
end 参数是可选的。如果未提供,则使用 this 值的长度。
注 2
如果 start 为负数,则视为 length +
start ,其中 length 是数组的长度。如果 end 为负数,则视为
length + end 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 k 为 0。
否则如果 relativeStart < 0,令 k 为 max (len +
relativeStart , 0)。
否则,令 k 为 min (relativeStart ,
len )。
如果 end 为 undefined ,令 relativeEnd 为
len ;否则令 relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 final 为 0。
否则如果 relativeEnd < 0,令 final 为 max (len +
relativeEnd , 0)。
否则,令 final 为 min (relativeEnd , len )。
重复,直到 k < final ,
令 Pk 为 ! ToString (𝔽 (k ))。
执行 ? Set (O , Pk ,
value , true )。
令 k 为 k + 1。
返回 O 。
注 3
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.8 Array.prototype.filter ( callback [ ,
thisArg ] )
注 1
callback 应该是一个接受三个参数并返回可转换为布尔值的函数。filter 会按升序对数组中每个元素调用
callback 一次,并构造一个包含所有 callback 返回 true
的值的新数组。callback 只会对数组中实际存在的元素调用,不会对数组中缺失的元素调用。
如果提供了 thisArg 参数,则每次调用 callback 时都会用作 this
值。如果未提供,则使用 undefined 。
callback 被调用时有三个参数:元素的值、元素的索引、被遍历的对象。
filter 不会直接修改它所调用的对象,但该对象可能会被 callback 的调用修改。
filter 处理的元素范围在第一次调用 callback 前就已确定。调用 filter
之后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被修改,则传递给 callback 的值是在
filter 访问该元素时的值;在 filter 调用开始后被删除且尚未被访问的元素不会被访问。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 A 为 ? ArraySpeciesCreate (O , 0)。
令 k 为 0。
令 to 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
令 selected 为 ToBoolean (? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »))。
如果 selected 为 true ,则
执行 ? CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (to )),
kValue )。
设置 to 为 to + 1。
设置 k 为 k + 1。
返回 A 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.9 Array.prototype.find ( predicate [ ,
thisArg ] )
注 1
该方法会按索引升序对数组的每个元素调用 predicate 一次,直到找到一个 predicate 返回可转换为
true 的值的元素。如果找到这样的元素,find
会立即返回该元素的值。否则,find 返回 undefined 。
更多信息见 FindViaPredicate 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 findRec 为 ? FindViaPredicate (O ,
len , ascending , predicate ,
thisArg )。
返回 findRec .[[Value]] 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.10 Array.prototype.findIndex ( predicate [ ,
thisArg ] )
注 1
该方法会按索引升序对数组的每个元素调用 predicate 一次,直到找到一个 predicate 返回可转换为
true 的值的元素。如果找到这样的元素,findIndex
会立即返回该元素的索引。否则,findIndex 返回 -1。
更多信息见 FindViaPredicate 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 findRec 为 ? FindViaPredicate (O ,
len , ascending , predicate ,
thisArg )。
返回 findRec .[[Index]] 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.11 Array.prototype.findLast ( predicate [ ,
thisArg ] )
注 1
该方法会按索引降序对数组的每个元素调用 predicate 一次,直到找到一个 predicate 返回可转换为
true 的值的元素。如果找到这样的元素,findLast
会立即返回该元素的值。否则,findLast 返回 undefined 。
更多信息见 FindViaPredicate 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 findRec 为 ? FindViaPredicate (O ,
len , descending , predicate ,
thisArg )。
返回 findRec .[[Value]] 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组对象。因此它可以转移到其他类型对象用作方法。
23.1.3.12 Array.prototype.findLastIndex ( predicate [
, thisArg ] )
注 1
该方法会按索引降序对数组的每个元素调用 predicate 一次,直到找到一个 predicate 返回可转换为
true 的值的元素。如果找到这样的元素,findLastIndex
会立即返回该元素的索引。否则,findLastIndex 返回 -1。
更多信息见 FindViaPredicate 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 findRec 为 ? FindViaPredicate (O ,
len , descending , predicate ,
thisArg )。
返回 findRec .[[Index]] 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组对象。因此它可以转移到其他类型对象用作方法。
23.1.3.12.1 FindViaPredicate ( O , len ,
direction , predicate , thisArg )
抽象操作 FindViaPredicate 接收参数 O (一个对象)、len (一个非负整数 )、direction (ascending
或 descending )、predicate (一个ECMAScript 语言值 )、和
thisArg (一个ECMAScript 语言值 ),返回一个包含字段
[[Index]] (一个整数 )和 [[Value]] (一个ECMAScript
语言值 )的记录 ,或抛出完成类型的
异常 。
O 应为类数组对象 或TypedArray 。该操作会按
direction 指示的顺序(升序或降序)对 O 的每个元素调用 predicate ,直到找到一个
predicate 返回可转换为 true
的值的元素。此时,该操作返回一个包含所找到元素索引和值的记录 。如果未找到这样的元素,则返回一个
记录 ,其索引为
-1 𝔽 ,值为 undefined 。
predicate 应为一个函数。对数组的每个元素调用时,传递三个参数:元素的值、元素的索引和被遍历的对象。其返回值会被转换为布尔值。
thisArg 会作为每次调用 predicate 时的 this 值。
该操作不会直接修改其调用的对象,但该对象可能会被 predicate 的调用修改。
处理的元素范围在首次调用 predicate 前(遍历开始前)就已确定。遍历后添加到数组的元素不会被 predicate
访问。如果数组中已存在的元素被修改,则传递给 predicate
的值为操作访问该元素时的值。在遍历开始后被删除且尚未被访问的元素依然会被访问,要么从原型获取,要么为 undefined 。
调用时执行以下步骤:
如果 IsCallable (predicate ) 为
false ,抛出 TypeError 异常。
如果 direction 是 ascending ,则
令 indices 为从 0(含)到 len (不含)区间内所有整数按升序排列的列表 。
否则,
令 indices 为从 0(含)到 len (不含)区间内所有整数按降序排列的列表 。
对于 indices 中的每个整数 k ,执行
令 Pk 为 ! ToString (𝔽 (k ))。
注:如果 O 是 TypedArray ,则下面对 Get
的调用会返回正常完成类型。
令 kValue 为 ? Get (O ,
Pk )。
令 testResult 为 ? Call (predicate ,
thisArg , « kValue , 𝔽 (k ),
O »)。
如果 ToBoolean (testResult )
为 true ,则返回 记录
{ [[Index]] : 𝔽 (k ), [[Value]] : kValue }。
返回 记录 {
[[Index]] : -1 𝔽 , [[Value]] : undefined }.
23.1.3.13 Array.prototype.flat ( [ depth ] )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 sourceLen 为 ? LengthOfArrayLike (O )。
令 depthNum 为 1。
如果 depth 不等于 undefined ,则
设置 depthNum 为 ? ToIntegerOrInfinity (depth )。
如果 depthNum < 0,设置 depthNum 为 0。
令 A 为 ? ArraySpeciesCreate (O , 0)。
执行 ? FlattenIntoArray (A ,
O , sourceLen , 0, depthNum )。
返回 A 。
23.1.3.13.1 FlattenIntoArray ( target ,
source , sourceLen , start , depth [ ,
mapperFunction [ , thisArg ] ] )
抽象操作 FlattenIntoArray 接收参数
target (一个对象)、source (一个对象)、sourceLen (一个非负整数 )、start (一个非负整数 )、depth (一个非负整数 或+∞),可选参数
mapperFunction (一个函数对象 )、thisArg (一个ECMAScript 语言值 ),返回包含 非负整数 的正常完成,或抛出完成 。调用时执行以下步骤:
断言 :如果
mapperFunction 存在,则 IsCallable (mapperFunction )
为 true ,thisArg 存在,且 depth 为 1。
令 targetIndex 为 start 。
令 sourceIndex 为 +0 𝔽 。
重复,直到 ℝ (sourceIndex ) <
sourceLen ,
令 P 为 ! ToString (sourceIndex )。
令 exists 为 ? HasProperty (source ,
P )。
如果 exists 为 true ,则
令 element 为 ? Get (source ,
P )。
如果 mapperFunction 存在,则
设置 element 为 ? Call (mapperFunction ,
thisArg , « element ,
sourceIndex , source »)。
令 shouldFlatten 为 false 。
如果 depth > 0,则
设置 shouldFlatten 为 ? IsArray (element )。
如果 shouldFlatten 为 true ,则
如果 depth = +∞,令 newDepth 为 +∞。
否则,令 newDepth 为 depth - 1。
令 elementLen 为 ? LengthOfArrayLike (element )。
设置 targetIndex 为 ? FlattenIntoArray (target ,
element , elementLen ,
targetIndex , newDepth )。
否则,
如果 targetIndex ≥ 253 - 1,抛出
TypeError 异常。
执行 ? CreateDataPropertyOrThrow (target ,
! ToString (𝔽 (targetIndex )),
element )。
设置 targetIndex 为 targetIndex +
1。
设置 sourceIndex 为 sourceIndex +
1 𝔽 。
返回 targetIndex 。
23.1.3.14 Array.prototype.flatMap ( mapperFunction [
, thisArg ] )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 sourceLen 为 ? LengthOfArrayLike (O )。
如果 IsCallable (mapperFunction )
为 false ,抛出 TypeError 异常。
令 A 为 ? ArraySpeciesCreate (O , 0)。
执行 ? FlattenIntoArray (A ,
O , sourceLen , 0, 1, mapperFunction ,
thisArg )。
返回 A 。
23.1.3.15 Array.prototype.forEach ( callback [ ,
thisArg ] )
注 1
callback 应该是一个接受三个参数的函数。forEach 对数组中实际存在的每个元素按升序调用
callback 一次。callback 只会对数组中实际存在的元素调用,不会对数组中缺失的元素调用。
如果提供了 thisArg 参数,则每次调用 callback 时都会用作 this
值。如果未提供,则使用 undefined 。
callback 被调用时有三个参数:元素的值、元素的索引、被遍历的对象。
forEach 不会直接修改它所调用的对象,但该对象可能会被 callback 的调用修改。
forEach 处理的元素范围在第一次调用 callback 前就已确定。调用 forEach
之后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被修改,则传递给 callback 的值是在
forEach 访问该元素时的值;在 forEach 调用开始后被删除且尚未被访问的元素不会被访问。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
执行 ? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »)。
设置 k 为 k + 1。
返回 undefined 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.16 Array.prototype.includes ( searchElement [
, fromIndex ] )
注 1
该方法会按升序将 searchElement 与数组的元素进行比较,使用 SameValueZero
算法,如果在任何位置找到,则返回 true ;否则返回 false 。
可选的第二个参数 fromIndex 默认为
+0 𝔽 (即搜索整个数组)。如果它大于等于数组长度,则返回
false ,即不会搜索数组。如果小于
-0 𝔽 ,则用作从数组末尾的偏移来计算 fromIndex 。如果计算得到的索引小于等于
+0 𝔽 ,则会搜索整个数组。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 len = 0,返回 false 。
令 n 为 ? ToIntegerOrInfinity (fromIndex )。
断言 :如果
fromIndex 为 undefined ,则 n 为 0。
如果 n = +∞,返回 false 。
否则如果 n = -∞,设置 n 为 0。
如果 n ≥ 0,则
令 k 为 n 。
否则,
令 k 为 len + n 。
如果 k < 0,设置 k 为 0。
重复,直到 k < len ,
令 elementK 为 ? Get (O ,
! ToString (𝔽 (k )))。
如果 SameValueZero (searchElement ,
elementK ) 为 true ,返回
true 。
设置 k 为 k + 1。
返回 false 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
注 3
该方法有意与类似的 indexOf 方法有两点不同。第一,它使用 SameValueZero 算法,而不是
IsStrictlyEqual ,从而可以检测
NaN 数组元素。第二,它不会跳过缺失的数组元素,而是将它们视为 undefined 。
23.1.3.17 Array.prototype.indexOf ( searchElement [ ,
fromIndex ] )
该方法使用 IsStrictlyEqual 算法,按升序将
searchElement 与数组中的元素进行比较,如果在一个或多个索引处找到,则返回最小的那个索引;否则返回
-1 𝔽 。
注 1
可选的第二个参数 fromIndex 默认为
+0 𝔽 (即搜索整个数组)。如果它大于等于数组长度,则返回
-1 𝔽 ,即不会搜索数组。如果它小于
-0 𝔽 ,则用作从数组末尾的偏移来计算 fromIndex 。如果计算得到的索引小于等于
+0 𝔽 ,则会搜索整个数组。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 len = 0,返回 -1 𝔽 。
令 n 为 ? ToIntegerOrInfinity (fromIndex )。
断言 :如果
fromIndex 为 undefined ,则 n 为 0。
如果 n = +∞,返回 -1 𝔽 。
否则如果 n = -∞,设置 n 为 0。
如果 n ≥ 0,则
令 k 为 n 。
否则,
令 k 为 len + n 。
如果 k < 0,设置 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 elementK 为 ? Get (O ,
Pk )。
如果 IsStrictlyEqual (searchElement ,
elementK ) 为 true ,返回 𝔽 (k )。
设置 k 为 k + 1。
返回 -1 𝔽 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.18 Array.prototype.join ( separator )
该方法将数组的元素转换为字符串,然后用 separator 分隔这些字符串并连接起来。如果没有提供分隔符,则使用单个逗号作为分隔符。
调用时按照以下步骤执行:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 separator 为 undefined ,令 sep 为
"," 。
否则,令 sep 为 ? ToString (separator )。
令 R 为空字符串。
令 k 为 0。
重复,直到 k < len ,
如果 k > 0,令 R 为 字符串拼接 R 和
sep 的结果。
令 element 为 ? Get (O ,
! ToString (𝔽 (k )))。
如果 element 既不是 undefined 也不是
null ,则
令 S 为 ? ToString (element )。
令 R 为 字符串拼接
R 和 S 的结果。
设置 k 为 k + 1。
返回 R 。
注
该方法被设计为泛型;它不要求其 this 值为数组。因此,它可以被转移到其他类型的对象上用作方法。
23.1.3.19 Array.prototype.keys ( )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
返回 CreateArrayIterator (O ,
key )。
23.1.3.20 Array.prototype.lastIndexOf ( searchElement
[ , fromIndex ] )
注 1
该方法会按降序将 searchElement 与数组的元素比较,使用 IsStrictlyEqual
算法,如果在一个或多个索引处找到,则返回最大的那个索引;否则返回 -1 𝔽 。
可选的第二个参数 fromIndex 默认为数组长度减一(即搜索整个数组)。如果它大于等于数组长度,则会搜索整个数组。如果它小于
-0 𝔽 ,则用作从数组末尾的偏移来计算 fromIndex 。如果计算得到的索引小于等于
+0 𝔽 ,则返回 -1 𝔽 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 len = 0,返回 -1 𝔽 。
如果 fromIndex 存在,令 n 为 ? ToIntegerOrInfinity (fromIndex );
否则令 n 为 len - 1。
如果 n = -∞,返回 -1 𝔽 。
如果 n ≥ 0,则
令 k 为 min (n , len -
1)。
否则,
令 k 为 len + n 。
重复,直到 k ≥ 0,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 elementK 为 ? Get (O ,
Pk )。
如果 IsStrictlyEqual (searchElement ,
elementK ) 为 true ,返回 𝔽 (k )。
设置 k 为 k - 1。
返回 -1 𝔽 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.21 Array.prototype.map ( callback [ ,
thisArg ] )
注 1
callback 应该是一个接受三个参数的函数。map 会按升序对数组中每个元素调用
callback 一次,并用结果构造一个新数组。callback
只会对数组中实际存在的元素调用,不会对数组中缺失的元素调用。
如果提供了 thisArg 参数,则每次调用 callback 时都会用作 this
值。如果未提供,则使用 undefined 。
callback 被调用时有三个参数:元素的值、元素的索引、被遍历的对象。
map 不会直接修改它所调用的对象,但该对象可能会被 callback 的调用修改。
map 处理的元素范围在第一次调用 callback 前就已确定。调用 map
之后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被修改,则传递给 callback 的值是在
map 访问该元素时的值;在 map 调用开始后被删除且尚未被访问的元素不会被访问。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 A 为 ? ArraySpeciesCreate (O ,
len )。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
令 mappedValue 为 ? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »)。
执行 ? CreateDataPropertyOrThrow (A ,
Pk , mappedValue )。
设置 k 为 k + 1。
返回 A 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.22 Array.prototype.pop ( )
注 1
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 len = 0,则
执行 ? Set (O ,
"length" , +0 𝔽 ,
true )。
返回 undefined 。
否则,
断言 :len > 0。
令 newLen 为 𝔽 (len - 1)。
令 index 为 ! ToString (newLen )。
令 element 为 ? Get (O ,
index )。
执行 ? DeletePropertyOrThrow (O ,
index )。
执行 ? Set (O ,
"length" , newLen , true )。
返回 element 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.23 Array.prototype.push ( ...items )
注 1
该方法将参数按出现顺序追加到数组末尾。它返回数组的新长度。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 argCount 为 items 中元素的数量。
如果 len + argCount > 253 - 1,抛出
TypeError 异常。
对于 items 的每个元素 E ,执行
执行 ? Set (O ,
! ToString (𝔽 (len )),
E , true )。
设置 len 为 len + 1。
执行 ? Set (O ,
"length" , 𝔽 (len ), true )。
返回 𝔽 (len )。
该方法的 "length" 属性为 1 𝔽 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.24 Array.prototype.reduce ( callback [ ,
initialValue ] )
注 1
callback 应为一个接受四个参数的函数。reduce 会对数组中第一个元素之后的每个元素按升序以函数形式调用
callback 一次。
callback 被调用时带四个参数:previousValue (上次调用 callback
的值)、currentValue (当前元素的值)、currentIndex 和被遍历的对象。首次调用
callback 时,previousValue 和 currentValue
可能有两种情况。如果调用 reduce 时提供了 initialValue ,则
previousValue 为 initialValue ,currentValue
为数组的第一个值。如果没有提供 initialValue ,则 previousValue
为数组的第一个值,currentValue 为第二个值。如果数组为空且未提供 initialValue ,会抛出
TypeError 。
reduce 不会直接修改其调用的对象,但对象可能会被 callback 的调用修改。
reduce 处理的元素范围在第一次调用 callback 前就已确定。调用 reduce
后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被修改,则传递给 callback 的值为
reduce 访问该元素时的值;在 reduce 调用开始后被删除且尚未被访问的元素不会被访问。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
如果 len = 0 且 initialValue 不存在,抛出 TypeError
异常。
令 k 为 0。
令 accumulator 为 undefined 。
如果 initialValue 存在,则
设置 accumulator 为 initialValue 。
否则,
令 kPresent 为 false 。
重复,直到 kPresent 为 false 且 k <
len ,
令 Pk 为 ! ToString (𝔽 (k ))。
设置 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
设置 accumulator 为 ? Get (O ,
Pk )。
设置 k 为 k + 1。
如果 kPresent 为 false ,抛出
TypeError 异常。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
设置 accumulator 为 ? Call (callback ,
undefined , « accumulator ,
kValue , 𝔽 (k ),
O »)。
设置 k 为 k + 1。
返回 accumulator 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.25 Array.prototype.reduceRight ( callback [ ,
initialValue ] )
注 1
callback 应为一个接受四个参数的函数。reduceRight
会对数组中第一个元素之后的每个元素按降序以函数形式调用 callback 一次。
callback 被调用时带四个参数:previousValue (上次调用 callback
的值)、currentValue (当前元素的值)、currentIndex
和被遍历的对象。首次调用该函数时,previousValue 和 currentValue 可能有两种情况。如果调用
reduceRight 时提供了 initialValue ,则 previousValue 为
initialValue ,currentValue 为数组的最后一个值。如果没有提供
initialValue ,则 previousValue 为数组的最后一个值,currentValue
为倒数第二个值。如果数组为空且未提供 initialValue ,会抛出 TypeError 。
reduceRight 不会直接修改其调用的对象,但对象可能会被 callback 的调用修改。
reduceRight 处理的元素范围在第一次调用 callback 前就已确定。调用
reduceRight 后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被
callback 修改,则传递给 callback 的值为 reduceRight
访问该元素时的值;在 reduceRight 调用开始后被删除且尚未被访问的元素不会被访问。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
如果 len = 0 且 initialValue 不存在,抛出 TypeError
异常。
令 k 为 len - 1。
令 accumulator 为 undefined 。
如果 initialValue 存在,则
设置 accumulator 为 initialValue 。
否则,
令 kPresent 为 false 。
重复,直到 kPresent 为 false 且 k ≥ 0,
令 Pk 为 ! ToString (𝔽 (k ))。
设置 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
设置 accumulator 为 ? Get (O ,
Pk )。
设置 k 为 k - 1。
如果 kPresent 为 false ,抛出
TypeError 异常。
重复,直到 k ≥ 0,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
设置 accumulator 为 ? Call (callback ,
undefined , « accumulator ,
kValue , 𝔽 (k ),
O »)。
设置 k 为 k - 1。
返回 accumulator 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.26 Array.prototype.reverse ( )
注 1
该方法重新排列数组元素,使其顺序颠倒。它返回反转后的数组。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 middle 为 floor (len / 2)。
令 lower 为 0。
重复,直到 lower ≠ middle ,
令 upper 为 len - lower - 1。
令 upperP 为 ! ToString (𝔽 (upper ))。
令 lowerP 为 ! ToString (𝔽 (lower ))。
令 lowerExists 为 ? HasProperty (O ,
lowerP )。
如果 lowerExists 为 true ,则
令 lowerValue 为 ? Get (O ,
lowerP )。
令 upperExists 为 ? HasProperty (O ,
upperP )。
如果 upperExists 为 true ,则
令 upperValue 为 ? Get (O ,
upperP )。
如果 lowerExists 为 true 且 upperExists
为 true ,则
执行 ? Set (O ,
lowerP , upperValue , true )。
执行 ? Set (O ,
upperP , lowerValue , true )。
否则如果 lowerExists 为 false 且
upperExists 为 true ,则
执行 ? Set (O ,
lowerP , upperValue , true )。
执行 ? DeletePropertyOrThrow (O ,
upperP )。
否则如果 lowerExists 为 true 且
upperExists 为 false ,则
执行 ? DeletePropertyOrThrow (O ,
lowerP )。
执行 ? Set (O ,
upperP , lowerValue , true )。
否则,
断言 :lowerExists 和
upperExists 都为 false 。
注:无操作需要执行。
设置 lower 为 lower + 1。
返回 O 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此,它可以被转移到其他类型的对象上用作方法。
23.1.3.27 Array.prototype.shift ( )
该方法移除数组的第一个元素并返回它。
调用时按照以下步骤执行:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 len = 0,则
执行 ? Set (O ,
"length" , +0 𝔽 ,
true )。
返回 undefined 。
令 first 为 ? Get (O ,
"0" )。
令 k 为 1。
重复,直到 k < len ,
令 from 为 ! ToString (𝔽 (k ))。
令 to 为 ! ToString (𝔽 (k - 1))。
令 fromPresent 为 ? HasProperty (O ,
from )。
如果 fromPresent 为 true ,则
令 fromValue 为 ? Get (O ,
from )。
执行 ? Set (O ,
to , fromValue , true )。
否则,
断言 :fromPresent 为
false 。
执行 ? DeletePropertyOrThrow (O ,
to )。
设置 k 为 k + 1。
执行 ? DeletePropertyOrThrow (O ,
! ToString (𝔽 (len - 1)))。
执行 ? Set (O ,
"length" , 𝔽 (len - 1), true )。
返回 first 。
注
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.28 Array.prototype.slice ( start ,
end )
该方法返回一个包含数组从元素 start 到(但不包括)元素 end 的元素的新数组(如果 end 是
undefined ,则一直到数组末尾)。如果 start 为负数,则视为 length + start ,其中 length
是数组长度。如果 end 为负数,则视为 length +
end ,其中 length 是数组长度。
调用时按照以下步骤执行:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 k 为 0。
否则如果 relativeStart < 0,令 k 为 max (len +
relativeStart , 0)。
否则,令 k 为 min (relativeStart ,
len )。
如果 end 为 undefined ,令 relativeEnd 为
len ;否则令 relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 final 为 0。
否则如果 relativeEnd < 0,令 final 为 max (len +
relativeEnd , 0)。
否则,令 final 为 min (relativeEnd , len )。
令 count 为 max (final - k , 0)。
令 A 为 ? ArraySpeciesCreate (O ,
count )。
令 n 为 0。
重复,直到 k < final ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
执行 ? CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (n )),
kValue )。
设置 k 为 k + 1。
设置 n 为 n + 1。
执行 ? Set (A ,
"length" , 𝔽 (n ), true )。
返回 A 。
注 1
第 15 步显式设置
"length" 属性,旨在确保即使 A 不是内建数组时长度也是正确的。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.29 Array.prototype.some ( callback [ ,
thisArg ] )
注 1
callback 应为一个接受三个参数并返回可转换为布尔值的函数。some 会对数组中实际存在的每个元素按升序调用
callback ,直到找到一个 callback 返回 true
的元素为止。如果找到这样的元素,some 会立即返回 true 。否则,some
返回 false 。callback 只会对数组中实际存在的元素调用,不会对数组中缺失的元素调用。
如果提供了 thisArg 参数,则每次调用 callback 时都会用作 this
值。如果未提供,则使用 undefined 。
callback 被调用时有三个参数:元素的值、元素的索引、被遍历的对象。
some 不会直接修改其调用的对象,但该对象可能会被 callback 的调用修改。
some 处理的元素范围在第一次调用 callback 前就已确定。调用 some
后添加到数组的元素不会被 callback 访问。如果数组中已存在的元素被修改,则传递给 callback 的值是在
some 访问该元素时的值;在 some
调用开始后被删除且尚未被访问的元素不会被访问。some 类似于数学中的“存在”量词。特别地,对于空数组,它返回
false 。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ? HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 kValue 为 ? Get (O ,
Pk )。
令 testResult 为 ToBoolean (? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »))。
如果 testResult 为 true ,返回
true 。
设置 k 为 k + 1。
返回 false 。
注 2
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.30 Array.prototype.sort ( comparator )
该方法对数组的元素进行排序。如果 comparator 不为 undefined ,则应为一个接受两个参数
x 和 y 的函数,若 x < y ,返回负数;若 x >
y ,返回正数;否则返回零。
调用时按照以下步骤执行:
如果 comparator 不为
undefined 且 IsCallable (comparator ) 为
false ,抛出 TypeError 异常。
令 obj 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (obj )。
令 SortCompare 为一个新的 抽象闭包 ,带参数
(x , y ),捕获 comparator 并在调用时执行以下步骤:
返回 ? CompareArrayElements (x ,
y , comparator )。
令 sortedList 为 ? SortIndexedProperties (obj ,
len , SortCompare , skip-holes )。
令 itemCount 为 sortedList 中元素的数量。
令 j 为 0。
重复,直到 j < itemCount ,
执行 ? Set (obj ,
! ToString (𝔽 (j )),
sortedList [j ], true )。
设置 j 为 j + 1。
注:第 SortIndexedProperties 步骤(见
5 )使用
skip-holes 。剩余索引会被删除,以保留排序前检测到并排除的空洞数量。
重复,直到 j < len ,
执行 ? DeletePropertyOrThrow (obj ,
! ToString (𝔽 (j )))。
设置 j 为 j + 1。
返回 obj 。
注 1
由于不存在的属性值总是大于 undefined 属性值,而 undefined
总是大于任何其他值(见 CompareArrayElements ),undefined
属性值总是排序到结果的末尾,其后是不存在的属性值。
注 2
在第 5 和 6 步骤中由 ToString
抽象操作
执行的方法调用,可能导致 SortCompare 行为不是一个 一致性比较器 。
注 3
该方法被设计为泛型;它不要求其 this 值为数组。因此,它可以被转移到其他类型的对象上用作方法。
23.1.3.30.1 SortIndexedProperties ( obj ,
len , SortCompare , holes )
抽象操作 SortIndexedProperties 接收参数 obj (一个对象)、len (一个非负整数 )、SortCompare (一个带有两个参数的抽象闭包 )、holes (skip-holes
或 read-through-holes ),返回包含 List
的正常完成,或抛出完成 。调用时执行以下步骤:
令 items 为一个新的空List 。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
如果 holes 为 skip-holes ,则
令 kRead 为 ? HasProperty (obj ,
Pk )。
否则,
断言 :holes 为
read-through-holes 。
令 kRead 为 true 。
如果 kRead 为 true ,则
令 kValue 为 ? Get (obj ,
Pk )。
将 kValue 添加到 items 。
设置 k 为 k + 1。
使用实现定义 的 对 SortCompare 的调用序列 对 items
进行排序。如果此过程中有任何调用返回 异常完成 ,则在进行任何进一步调用
SortCompare 前停止并返回该 Completion
Record 。
返回 items 。
排序顺序(sort order) 指的是上述算法中第 4
步执行后 items 的排列顺序。若 SortCompare 不是 items 元素的 一致性比较器 ,则 排序顺序 是
实现定义 。当通过 Array.prototype.sort 或 Array.prototype.toSorted 调用
SortIndexedProperties 时,如果 comparator 为 undefined ,且所有传给
SortCompare 的特定参数的 ToString 调用结果不一致,则 排序顺序 也是
实现定义 。
除非 排序顺序
被指定为 实现定义 ,否则必须满足以下所有条件:
存在对小于 itemCount 的非负整数 的某个数学排列 π,使得对于每个小于 itemCount
的非负整数
j ,有 old[j ] 与 new[π(j )] 完全一致。
对所有小于 itemCount 的非负整数 j 和 k ,如果 ℝ (SortCompare (old[j ],
old[k ])) < 0 ,则 π(j )
< π(k ) 。
对所有 j < k < itemCount 的非负整数 j 和
k ,如果 ℝ (SortCompare (old[j ],
old[k ])) = 0 ,则 π(j )
< π(k ) ;即排序是稳定的。
此处记号 old[j ] 表示第 4
步执行前 items [j ],而 new[j ] 表示执行后 items [j ]。
抽象闭包或函数 comparator 对于值集合 S 来说,如果对集合 S 中所有可能的值
a 、b 、c (可能相同)均满足以下要求,则称其为 一致性比较器 。记号 a <C
b 表示 ℝ (comparator (a ,
b )) < 0 ;a =C
b 表示 ℝ (comparator (a ,
b )) = 0 ;a
>C b 表示 ℝ (comparator (a ,
b )) > 0 。
对于给定的 a 和 b ,每次调用 comparator (a ,
b ) 总是返回相同的值 v 。此外,v 是一个
Number ,且 v 不是 NaN 。这意味着对于一对
a 和 b ,a <C b 、a
=C b 、a >C b 三者必有其一为真。
调用 comparator (a , b ) 不会修改 obj
或其原型链上的任何对象。
a =C a (自反性)
如果 a =C b ,则 b =C
a (对称性)
如果 a =C b 且 b =C
c ,则 a =C c (传递性)
如果 a <C b 且 b <C
c ,则 a <C c (传递性)
如果 a >C b 且 b >C
c ,则 a >C c (传递性)
注
上述条件是保证 comparator 将集合 S 划分为等价类并且这些等价类是全序所必需且充分的条件。
23.1.3.30.2 CompareArrayElements ( x ,
y , comparator )
抽象操作 CompareArrayElements 接收参数 x (一个ECMAScript
语言值 )、y (一个ECMAScript
语言值 )、comparator (一个函数对象 或undefined ),返回包含 Number
的正常完成,或异常完成 。调用时执行以下步骤:
如果 x 和 y 都是 undefined ,返回
+0 𝔽 。
如果 x 是 undefined ,返回
1 𝔽 。
如果 y 是 undefined ,返回
-1 𝔽 。
如果 comparator 不为 undefined ,则
令 v 为 ? ToNumber (? Call (comparator ,
undefined , « x , y »))。
如果 v 是 NaN ,返回
+0 𝔽 。
返回 v 。
令 xString 为 ? ToString (x )。
令 yString 为 ? ToString (y )。
令 xSmaller 为 ! IsLessThan (xString ,
yString , true )。
如果 xSmaller 为 true ,返回
-1 𝔽 。
令 ySmaller 为 ! IsLessThan (yString ,
xString , true )。
如果 ySmaller 为 true ,返回
1 𝔽 。
返回 +0 𝔽 。
23.1.3.31 Array.prototype.splice ( start ,
deleteCount , ...items )
注 1
该方法从整数索引 start 开始,删除数组中的 deleteCount 个元素,并用 items
的元素替换它们。它返回一个包含被删除元素(如有)的数组。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 actualStart 为 0。
否则如果 relativeStart < 0,令 actualStart 为 max (len
+ relativeStart , 0)。
否则,令 actualStart 为 min (relativeStart ,
len )。
令 itemCount 为 items 中元素的数量。
如果未传入 start ,则
令 actualDeleteCount 为 0。
否则如果未传入 deleteCount ,则
令 actualDeleteCount 为 len - actualStart 。
否则,
令 dc 为 ? ToIntegerOrInfinity (deleteCount )。
令 actualDeleteCount 为将 dc 限制在 0 到 len -
actualStart 之间的结果。
如果 len + itemCount - actualDeleteCount >
253 - 1,抛出 TypeError 异常。
令 A 为 ? ArraySpeciesCreate (O ,
actualDeleteCount )。
令 k 为 0。
重复,直到 k < actualDeleteCount ,
令 from 为 ! ToString (𝔽 (actualStart +
k ))。
如果 ? HasProperty (O ,
from ) 为 true ,则
令 fromValue 为 ? Get (O ,
from )。
执行 ? CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (k )),
fromValue )。
设置 k 为 k + 1。
执行 ? Set (A ,
"length" , 𝔽 (actualDeleteCount ),
true )。
如果 itemCount < actualDeleteCount ,则
设置 k 为 actualStart 。
重复,直到 k < (len -
actualDeleteCount ),
令 from 为 ! ToString (𝔽 (k +
actualDeleteCount ))。
令 to 为 ! ToString (𝔽 (k +
itemCount ))。
如果 ? HasProperty (O ,
from ) 为 true ,则
令 fromValue 为 ? Get (O ,
from )。
执行 ? Set (O ,
to , fromValue ,
true )。
否则,
执行 ? DeletePropertyOrThrow (O ,
to )。
设置 k 为 k + 1。
设置 k 为 len 。
重复,直到 k > (len -
actualDeleteCount + itemCount ),
执行 ? DeletePropertyOrThrow (O ,
! ToString (𝔽 (k - 1)))。
设置 k 为 k - 1。
否则如果 itemCount > actualDeleteCount ,则
设置 k 为 (len - actualDeleteCount )。
重复,直到 k > actualStart ,
令 from 为 ! ToString (𝔽 (k +
actualDeleteCount - 1))。
令 to 为 ! ToString (𝔽 (k +
itemCount - 1))。
如果 ? HasProperty (O ,
from ) 为 true ,则
令 fromValue 为 ? Get (O ,
from )。
执行 ? Set (O ,
to , fromValue ,
true )。
否则,
执行 ? DeletePropertyOrThrow (O ,
to )。
设置 k 为 k - 1。
设置 k 为 actualStart 。
对于 items 的每个元素 E ,执行
执行 ? Set (O ,
! ToString (𝔽 (k )),
E , true )。
设置 k 为 k + 1。
执行 ? Set (O ,
"length" , 𝔽 (len - actualDeleteCount +
itemCount ), true )。
返回 A 。
注 2
在第 15 和 20 步中显式设置
"length" 属性,旨在确保即使操作对象不是内建数组时长度也是正确的。
注 3
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.32 Array.prototype.toLocaleString ( [
reserved1 [ , reserved2 ] ] )
包含 ECMA-402 国际化 API 的 ECMAScript 实现必须按照 ECMA-402 规范实现此方法。如果 ECMAScript 实现不包含 ECMA-402
API,则使用下面对该方法的规范。
注 1
此方法的可选参数含义在 ECMA-402 规范中定义;不包含 ECMA-402 支持的实现不得将这些参数位置用于其他用途。
该方法调用时执行以下步骤:
令 array 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (array )。
令 separator 为适用于 宿主环境 当前区域设置的 实现定义 列表分隔符字符串值(如 ",
" )。
令 R 为空字符串。
令 k 为 0。
重复,直到 k < len ,
如果 k > 0,令 R 为 字符串拼接 R 和
separator 的结果。
令 element 为 ? Get (array ,
! ToString (𝔽 (k )))。
如果 element 既不是 undefined 也不是
null ,则
令 S 为 ? ToString (? Invoke (element ,
"toLocaleString" ))。
令 R 为 字符串拼接
R 和 S 的结果。
设置 k 为 k + 1。
返回 R 。
注 2
该方法使用元素各自的 toLocaleString
方法将数组元素转换为字符串,然后用实现定义的、区分区域设置的分隔符字符串把这些字符串连接起来。此方法类似于 toString,但目的是生成符合
宿主环境 当前区域习惯的本地化结果。
注 3
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.33 Array.prototype.toReversed ( )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 A 为 ? ArrayCreate (len )。
令 k 为 0。
重复,直到 k < len ,
令 from 为 ! ToString (𝔽 (len -
k - 1))。
令 Pk 为 ! ToString (𝔽 (k ))。
令 fromValue 为 ? Get (O ,
from )。
执行 ! CreateDataPropertyOrThrow (A ,
Pk , fromValue )。
设置 k 为 k + 1。
返回 A 。
23.1.3.34 Array.prototype.toSorted ( comparator )
该方法调用时执行以下步骤:
如果 comparator 不为 undefined 且 IsCallable (comparator ) 为
false ,抛出 TypeError 异常。
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 A 为 ? ArrayCreate (len )。
令 SortCompare 为一个新的 抽象闭包 ,带参数
(x , y ),捕获 comparator 并在调用时执行以下步骤:
返回 ? CompareArrayElements (x ,
y , comparator )。
令 sortedList 为 ? SortIndexedProperties (O ,
len , SortCompare , read-through-holes )。
令 j 为 0。
重复,直到 j < len ,
执行 ! CreateDataPropertyOrThrow (A ,
! ToString (𝔽 (j )),
sortedList [j ])。
设置 j 为 j + 1。
返回 A 。
23.1.3.35 Array.prototype.toSpliced ( start ,
skipCount , ...items )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 actualStart 为 0。
否则如果 relativeStart < 0,令 actualStart 为 max (len
+ relativeStart , 0)。
否则,令 actualStart 为 min (relativeStart ,
len )。
令 insertCount 为 items 中元素的数量。
如果未传入 start ,则
令 actualSkipCount 为 0。
否则如果未传入 skipCount ,则
令 actualSkipCount 为 len - actualStart 。
否则,
令 sc 为 ? ToIntegerOrInfinity (skipCount )。
令 actualSkipCount 为将 sc 限制在 0 到 len -
actualStart 之间的结果。
令 newLen 为 len + insertCount -
actualSkipCount 。
如果 newLen > 253 - 1,抛出 TypeError
异常。
令 A 为 ? ArrayCreate (newLen )。
令 i 为 0。
令 r 为 actualStart + actualSkipCount 。
重复,直到 i < actualStart ,
令 Pi 为 ! ToString (𝔽 (i ))。
令 iValue 为 ? Get (O , Pi )。
执行 ! CreateDataPropertyOrThrow (A ,
Pi , iValue )。
设置 i 为 i + 1。
对于 items 的每个元素 E ,执行
令 Pi 为 ! ToString (𝔽 (i ))。
执行 ! CreateDataPropertyOrThrow (A ,
Pi , E )。
设置 i 为 i + 1。
重复,直到 i < newLen ,
令 Pi 为 ! ToString (𝔽 (i ))。
令 from 为 ! ToString (𝔽 (r ))。
令 fromValue 为 ? Get (O ,
from )。
执行 ! CreateDataPropertyOrThrow (A ,
Pi , fromValue )。
设置 i 为 i + 1。
设置 r 为 r + 1。
返回 A 。
23.1.3.36 Array.prototype.toString ( )
该方法调用时执行以下步骤:
令 array 为 ? ToObject (this 值)。
令 func 为 ? Get (array ,
"join" )。
如果 IsCallable (func ) 为
false ,则将 func 设为内建函数 %Object.prototype.toString%。
返回 ? Call (func , array )。
注
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.37 Array.prototype.unshift ( ...items )
该方法将参数添加到数组的开头,其在数组中的顺序与参数列表中的顺序相同。
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 argCount 为 items 中元素的数量。
如果 argCount > 0,则
如果 len + argCount > 253 - 1,抛出
TypeError 异常。
令 k 为 len 。
重复,直到 k > 0,
令 from 为 ! ToString (𝔽 (k - 1))。
令 to 为 ! ToString (𝔽 (k +
argCount - 1))。
令 fromPresent 为 ? HasProperty (O ,
from )。
如果 fromPresent 为 true ,则
令 fromValue 为 ? Get (O ,
from )。
执行 ? Set (O ,
to , fromValue ,
true )。
否则,
断言 :
fromPresent 为 false 。
执行 ? DeletePropertyOrThrow (O ,
to )。
设置 k 为 k - 1。
令 j 为 +0 𝔽 。
对于 items 的每个元素 E ,执行
执行 ? Set (O ,
! ToString (j ),
E , true )。
设置 j 为 j +
1 𝔽 。
执行 ? Set (O ,
"length" , 𝔽 (len + argCount ),
true )。
返回 𝔽 (len + argCount )。
该方法的 "length" 属性为 1 𝔽 。
注
该方法被设计为泛型;它不要求其 this 值为数组。因此它可以转移到其他类型对象用作方法。
23.1.3.38 Array.prototype.values ( )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
返回 CreateArrayIterator (O ,
value )。
23.1.3.39 Array.prototype.with ( index ,
value )
该方法调用时执行以下步骤:
令 O 为 ? ToObject (this 值)。
令 len 为 ? LengthOfArrayLike (O )。
令 relativeIndex 为 ? ToIntegerOrInfinity (index )。
如果 relativeIndex ≥ 0,令 actualIndex 为
relativeIndex 。
否则,令 actualIndex 为 len + relativeIndex 。
如果 actualIndex ≥ len 或 actualIndex < 0,抛出
RangeError 异常。
令 A 为 ? ArrayCreate (len )。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
如果 k = actualIndex ,令 fromValue 为
value 。
否则,令 fromValue 为 ? Get (O , Pk )。
执行 ! CreateDataPropertyOrThrow (A ,
Pk , fromValue )。
设置 k 为 k + 1。
返回 A 。
23.1.3.40 Array.prototype [ %Symbol.iterator% ] ( )
%Symbol.iterator% 属性的初始值是
%Array.prototype.values%,定义见 23.1.3.38 。
23.1.3.41 Array.prototype [ %Symbol.unscopables% ]
%Symbol.unscopables% 数据属性
的初始值为通过以下步骤创建的对象:
令 unscopableList 为 OrdinaryObjectCreate (null )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"at" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"copyWithin" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"entries" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"fill" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"find" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"findIndex" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"findLast" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"findLastIndex" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"flat" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"flatMap" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"includes" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"keys" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"toReversed" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"toSorted" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"toSpliced" , true )。
执行 ! CreateDataPropertyOrThrow (unscopableList ,
"values" , true )。
返回 unscopableList 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
注
该对象的自有属性名是在 ECMAScript 2015 规范之前未作为 Array.prototype 标准属性包含的属性名。这些名称在
with 语句绑定时会被忽略,以保持现有代码的行为,这些代码可能在外部作用域中使用其中的某个名称作为绑定,而该作用域被
with 语句(其绑定对象为数组)所遮蔽。
"with" 未被包含在 unscopableList 中的原因是它已经是一个 保留字 。
23.1.4 数组实例的属性
数组实例是 数组特异对象 ,并具有为此类对象指定的内部方法。数组实例继承自 Array 原型对象 的属性。
数组实例有一个 "length" 属性,以及一组带有 数组索引 名称的可枚举属性。
23.1.4.1 length
Array 实例的 "length" 属性是一个 数据属性 ,其值总是数值上大于每个名称为 数组索引 、且可配置的自有属性的名称。
"length" 属性最初拥有属性 { [[Writable]] :
true , [[Enumerable]] : false ,
[[Configurable]] : false }。
注
减少 "length" 属性的值会导致删除其 数组索引
介于旧值和新值之间的自有数组元素。但不可配置属性不能被删除。试图将数组的 "length" 属性设置为小于或等于现有不可配置
数组索引 属性的最大数值自有 属性名 时,length 会被设置为比该不可配置数值自有 属性名 大 1 的数值。见 10.4.2.1 。
23.1.5 数组迭代器对象
数组迭代器 是一个表示对某个特定数组实例对象的特定迭代的对象。数组迭代器对象没有命名的 构造函数 。数组迭代器对象是通过调用数组实例对象的某些方法创建的。
23.1.5.1 CreateArrayIterator ( array , kind
)
抽象操作 CreateArrayIterator 接收参数 array (一个对象)和
kind (key+value 、key 或
value ),返回一个对象。用于为返回此类 迭代器 的 Array 方法创建
迭代器 对象。调用时执行以下步骤:
令 iterator 为 OrdinaryObjectCreate (%ArrayIteratorPrototype% ,
« [[IteratedArrayLike]] , [[ArrayLikeNextIndex]] , [[ArrayLikeIterationKind]] »)。
设置 iterator .[[IteratedArrayLike]] 为
array 。
设置 iterator .[[ArrayLikeNextIndex]] 为 0。
设置 iterator .[[ArrayLikeIterationKind]] 为
kind 。
返回 iterator 。
23.1.5.2 %ArrayIteratorPrototype% 对象
%ArrayIteratorPrototype% 对象:
23.1.5.2.1 %ArrayIteratorPrototype%.next ( )
令 O 为 this 值。
如果 O 不是对象 ,抛出
TypeError 异常。
如果 O 不具有 数组迭代器 实例(23.1.5.3 )的所有内部槽,抛出
TypeError 异常。
令 array 为 O .[[IteratedArrayLike]] 。
如果 array 为 undefined ,返回 CreateIteratorResultObject (undefined ,
true )。
令 index 为 O .[[ArrayLikeNextIndex]] 。
令 kind 为 O .[[ArrayLikeIterationKind]] 。
如果 array 具有 [[TypedArrayName]] 内部槽,则
令 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (array ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,抛出 TypeError 异常。
令 len 为 TypedArrayLength (taRecord )。
否则,
令 len 为 ? LengthOfArrayLike (array )。
如果 index ≥ len ,则
设置 O .[[IteratedArrayLike]] 为
undefined 。
返回 CreateIteratorResultObject (undefined ,
true )。
设置 O .[[ArrayLikeNextIndex]] 为
index + 1。
令 indexNumber 为 𝔽 (index )。
如果 kind 是 key ,则
令 result 为 indexNumber 。
否则,
令 elementKey 为 ! ToString (indexNumber )。
令 elementValue 为 ? Get (array ,
elementKey )。
如果 kind 是 value ,则
令 result 为 elementValue 。
否则,
断言 : kind 是
key+value 。
令 result 为 CreateArrayFromList («
indexNumber , elementValue »)。
返回 CreateIteratorResultObject (result ,
false )。
23.1.5.2.2 %ArrayIteratorPrototype% [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"Array Iterator" 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
true }。
23.1.5.3 数组迭代器实例的属性
数组迭代器 实例是 普通对象 ,继承自 %ArrayIteratorPrototype%
内建对象的属性。数组迭代器 实例创建时具有 表 74
中列出的内部槽。
表 74:数组迭代器 实例的内部槽
内部槽
类型
描述
[[IteratedArrayLike]]
一个对象或 undefined
被迭代的 类数组对象 。
[[ArrayLikeNextIndex]]
非负整数
该迭代器 要检查的下一个元素的整数索引 。
[[ArrayLikeIterationKind]]
key+value 、key 或
value
标识每次迭代返回什么类型值的值。
23.2 TypedArray 对象
TypedArray 展示了一个底层二进制数据缓冲区(25.1 )的类数组视图。TypedArray 元素类型 是所有 TypedArray
实例元素所具有的底层二进制标量数据类型。每种支持的元素类型都有一个不同的 TypedArray 构造函数 ,见 表 75 。表 75 中的每个 构造函数 都有一个对应的不同的原型对象。
表 75:TypedArray 构造函数
构造函数 名称及内建对象
元素类型
元素大小
转换操作
描述
Int8Array
%Int8Array%
int8
1
ToInt8
8 位二进制补码有符号整数
Uint8Array
%Uint8Array%
uint8
1
ToUint8
8 位无符号整数
Uint8ClampedArray
%Uint8ClampedArray%
uint8clamped
1
ToUint8Clamp
8 位无符号整数 (夹紧转换)
Int16Array
%Int16Array%
int16
2
ToInt16
16 位二进制补码有符号整数
Uint16Array
%Uint16Array%
uint16
2
ToUint16
16 位无符号整数
Int32Array
%Int32Array%
int32
4
ToInt32
32 位二进制补码有符号整数
Uint32Array
%Uint32Array%
uint32
4
ToUint32
32 位无符号整数
BigInt64Array
%BigInt64Array%
bigint64
8
ToBigInt64
64 位二进制补码有符号整数
BigUint64Array
%BigUint64Array%
biguint64
8
ToBigUint64
64 位无符号整数
Float16Array
%Float16Array%
float16
2
16 位 IEEE 浮点数
Float32Array
%Float32Array%
float32
4
32 位 IEEE 浮点数
Float64Array
%Float64Array%
float64
8
64 位 IEEE 浮点数
在下述定义中,对 TypedArray 的引用应替换为上表中相应的 构造函数 名称。
23.2.1 %TypedArray% 内建对象
%TypedArray% 内建对象:
是一个 构造函数
函数对象 ,所有 TypedArray 构造函数 对象都继承自它。
与其对应的原型对象一起,提供所有 TypedArray 构造函数 及其实例继承的公共属性。
没有全局名称,也不会作为 全局对象 的属性出现。
作为各类 TypedArray 构造函数 的抽象超类。
因为它是一个抽象类 构造函数 ,所以调用会抛出错误。TypedArray 构造函数 不会对它执行
super 调用。
23.2.1.1 %TypedArray% ( )
该函数被调用时执行以下步骤:
抛出 TypeError 异常。
该函数的 "length" 属性为
+0 𝔽 。
23.2.2 %TypedArray% 内建对象的属性
%TypedArray% 内建对象:
23.2.2.1 %TypedArray%.from ( source [ ,
mapper [ , thisArg ] ] )
该方法被调用时执行以下步骤:
令 C 为 this 值。
如果 IsConstructor (C ) 为
false ,抛出 TypeError 异常。
如果 mapper 为 undefined ,则
令 mapping 为 false 。
否则,
如果 IsCallable (mapper )
为 false ,抛出 TypeError 异常。
令 mapping 为 true 。
令 usingIterator 为 ? GetMethod (source , %Symbol.iterator% ).
如果 usingIterator 不为 undefined ,则
令 values 为 ? IteratorToList (? GetIteratorFromMethod (source ,
usingIterator ))。
令 len 为 values 中元素的数量。
令 targetObj 为 ? TypedArrayCreateFromConstructor (C ,
« 𝔽 (len ) »)。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 values 的第一个元素。
从 values 移除第一个元素。
如果 mapping 为 true ,则
令 mappedValue 为 ? Call (mapper ,
thisArg , « kValue , 𝔽 (k ) »)。
否则,
令 mappedValue 为 kValue 。
执行 ? Set (targetObj ,
Pk , mappedValue , true )。
设置 k 为 k + 1。
断言 :values 现在是一个空的 List 。
返回 targetObj 。
注:source 不是 可迭代对象 ,所以假定它已经是 类数组对象 。
令 arrayLike 为 ! ToObject (source )。
令 len 为 ? LengthOfArrayLike (arrayLike )。
令 targetObj 为 ? TypedArrayCreateFromConstructor (C ,
« 𝔽 (len ) »)。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ? Get (arrayLike ,
Pk )。
如果 mapping 为 true ,则
令 mappedValue 为 ? Call (mapper ,
thisArg , « kValue , 𝔽 (k ) »)。
否则,
令 mappedValue 为 kValue 。
执行 ? Set (targetObj ,
Pk , mappedValue , true )。
设置 k 为 k + 1。
返回 targetObj 。
23.2.2.2 %TypedArray%.of ( ...items )
该方法被调用时执行以下步骤:
令 len 为 items 中元素的数量。
令 C 为 this 值。
如果 IsConstructor (C ) 为
false ,抛出 TypeError 异常。
令 newObj 为 ? TypedArrayCreateFromConstructor (C ,
« 𝔽 (len ) »)。
令 k 为 0。
重复,直到 k < len ,
令 kValue 为 items [k ]。
令 Pk 为 ! ToString (𝔽 (k ))。
执行 ? Set (newObj ,
Pk , kValue , true )。
设置 k 为 k + 1。
返回 newObj 。
23.2.2.3 %TypedArray%.prototype
%TypedArray% .prototype
的初始值为 %TypedArray%
原型对象 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
23.2.2.4 get %TypedArray% [ %Symbol.species% ]
%TypedArray% [%Symbol.species%]
是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
返回 this 值。
该函数的 "name" 属性值为 "get [Symbol.species]" 。
注
%TypedArray.prototype%
的方法通常使用其 this 值的 构造函数 来创建派生对象。但是,子类构造函数 可以通过重新定义其 %Symbol.species% 属性来覆盖该默认行为。
23.2.3 %TypedArray% 原型对象的属性
%TypedArray% 原型对象 :
拥有一个 [[Prototype]] 内部槽,其值为 %Object.prototype% 。
即 %TypedArray.prototype% 。
是一个 普通对象 。
没有 [[ViewedArrayBuffer]] 或其它 TypedArray 实例对象专有的内部槽。
23.2.3.1 %TypedArray%.prototype.at ( index )
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 relativeIndex 为 ? ToIntegerOrInfinity (index )。
如果 relativeIndex ≥ 0,则
令 k 为 relativeIndex 。
否则,
令 k 为 len + relativeIndex 。
如果 k < 0 或 k ≥ len ,返回
undefined 。
返回 ! Get (O , ! ToString (𝔽 (k )))。
23.2.3.2 get %TypedArray%.prototype.buffer
%TypedArray% .prototype.buffer
是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[TypedArrayName]] )。
断言 :
O 具有 [[ViewedArrayBuffer]] 内部槽。
令 buffer 为 O .[[ViewedArrayBuffer]] 。
返回 buffer 。
23.2.3.3 get %TypedArray%.prototype.byteLength
%TypedArray% .prototype.byteLength
是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[TypedArrayName]] )。
断言 :
O 具有 [[ViewedArrayBuffer]] 内部槽。
令 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
令 size 为 TypedArrayByteLength (taRecord )。
返回 𝔽 (size )。
23.2.3.4 get %TypedArray%.prototype.byteOffset
%TypedArray% .prototype.byteOffset
是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[TypedArrayName]] )。
断言 :
O 具有 [[ViewedArrayBuffer]] 内部槽。
令 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,返回 +0 𝔽 。
令 offset 为 O .[[ByteOffset]] 。
返回 𝔽 (offset )。
23.2.3.5 %TypedArray%.prototype.constructor
%TypedArray% .prototype.constructor
的初始值为 %TypedArray% 。
23.2.3.6 %TypedArray%.prototype.copyWithin ( target ,
start [ , end ] )
该方法的参数解释和用法与 23.1.3.4 中定义的
Array.prototype.copyWithin 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 relativeTarget 为 ? ToIntegerOrInfinity (target )。
如果 relativeTarget = -∞,令 targetIndex 为 0。
否则如果 relativeTarget < 0,令 targetIndex 为 max (len
+ relativeTarget , 0)。
否则,令 targetIndex 为 min (relativeTarget ,
len )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 startIndex 为 0。
否则如果 relativeStart < 0,令 startIndex 为 max (len
+ relativeStart , 0)。
否则,令 startIndex 为 min (relativeStart ,
len )。
如果 end 为 undefined ,令 relativeEnd 为
len ;否则令 relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 endIndex 为 0。
否则如果 relativeEnd < 0,令 endIndex 为 max (len
+ relativeEnd , 0)。
否则,令 endIndex 为 min (relativeEnd , len )。
令 count 为 min (endIndex -
startIndex , len - targetIndex )。
如果 count > 0,则
注:拷贝操作必须以保持源数据比特级编码的方式执行。
令 buffer 为 O .[[ViewedArrayBuffer]] 。
设置 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,抛出 TypeError 异常。
设置 len 为 TypedArrayLength (taRecord )。
令 elementSize 为 TypedArrayElementSize (O )。
令 byteOffset 为 O .[[ByteOffset]] 。
令 bufferByteLimit 为 (len × elementSize )
+ byteOffset 。
令 toByteIndex 为 (targetIndex ×
elementSize ) + byteOffset 。
令 fromByteIndex 为 (startIndex ×
elementSize ) + byteOffset 。
令 countBytes 为 count × elementSize 。
如果 fromByteIndex < toByteIndex 且
toByteIndex < fromByteIndex +
countBytes ,则
令 direction 为 -1。
设置 fromByteIndex 为 fromByteIndex +
countBytes - 1。
设置 toByteIndex 为 toByteIndex +
countBytes - 1。
否则,
令 direction 为 1。
重复,直到 countBytes > 0,
如果 fromByteIndex < bufferByteLimit 且
toByteIndex < bufferByteLimit ,则
令 value 为 GetValueFromBuffer (buffer ,
fromByteIndex , uint8 ,
true , unordered )。
执行 SetValueInBuffer (buffer ,
toByteIndex , uint8 ,
value , true ,
unordered )。
设置 fromByteIndex 为 fromByteIndex +
direction 。
设置 toByteIndex 为 toByteIndex +
direction 。
设置 countBytes 为 countBytes - 1。
否则,
设置 countBytes 为 0。
返回 O 。
23.2.3.7 %TypedArray%.prototype.entries ( )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? ValidateTypedArray (O ,
seq-cst )。
返回 CreateArrayIterator (O ,
key+value )。
23.2.3.8 %TypedArray%.prototype.every ( callback [ ,
thisArg ] )
该方法的参数解释和用法与 23.1.3.6 中定义的
Array.prototype.every 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
令 testResult 为 ToBoolean (? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »))。
如果 testResult 为 false ,返回
false 。
设置 k 为 k + 1。
返回 true 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.9 %TypedArray%.prototype.fill ( value [ ,
start [ , end ] ] )
该方法的参数解释和用法与 23.1.3.7 中定义的
Array.prototype.fill 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 O .[[ContentType]] 为
bigint ,将 value 设为 ? ToBigInt (value )。
否则,将 value 设为 ? ToNumber (value )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 startIndex 为 0。
否则如果 relativeStart < 0,令 startIndex 为 max (len
+ relativeStart , 0)。
否则,令 startIndex 为 min (relativeStart ,
len )。
如果 end 为 undefined ,令 relativeEnd 为
len ;否则令 relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 endIndex 为 0。
否则如果 relativeEnd < 0,令 endIndex 为 max (len
+ relativeEnd , 0)。
否则,令 endIndex 为 min (relativeEnd , len )。
设置 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,抛出 TypeError 异常。
设置 len 为 TypedArrayLength (taRecord )。
设置 endIndex 为 min (endIndex , len )。
令 k 为 startIndex 。
重复,直到 k < endIndex ,
令 Pk 为 ! ToString (𝔽 (k ))。
执行 ! Set (O ,
Pk , value , true )。
设置 k 为 k + 1。
返回 O 。
23.2.3.10 %TypedArray%.prototype.filter ( callback [
, thisArg ] )
该方法的参数解释和用法与 23.1.3.8 中定义的
Array.prototype.filter 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 kept 为一个新的空 List 。
令 captured 为 0。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
令 selected 为 ToBoolean (? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »))。
如果 selected 为 true ,则
将 kValue 添加到 kept 。
设置 captured 为 captured + 1。
设置 k 为 k + 1。
令 A 为 ? TypedArraySpeciesCreate (O , «
𝔽 (captured ) »)。
令 n 为 0。
对于 kept 的每个元素 e ,执行
执行 ! Set (A ,
! ToString (𝔽 (n )),
e , true )。
设置 n 为 n + 1。
返回 A 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.11 %TypedArray%.prototype.find ( predicate [ ,
thisArg ] )
该方法的参数解释和用法与 23.1.3.9 中定义的
Array.prototype.find 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 findRec 为 ? FindViaPredicate (O ,
len , ascending , predicate ,
thisArg )。
返回 findRec .[[Value]] 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.12 %TypedArray%.prototype.findIndex (
predicate [ , thisArg ] )
该方法的参数解释和用法与 23.1.3.10 中定义的
Array.prototype.findIndex 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 findRec 为 ? FindViaPredicate (O ,
len , ascending , predicate ,
thisArg )。
返回 findRec .[[Index]] 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.13 %TypedArray%.prototype.findLast ( predicate
[ , thisArg ] )
该方法的参数解释和用法与 23.1.3.11 中定义的
Array.prototype.findLast 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 findRec 为 ? FindViaPredicate (O ,
len , descending , predicate ,
thisArg )。
返回 findRec .[[Value]] 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.14 %TypedArray%.prototype.findLastIndex (
predicate [ , thisArg ] )
该方法的参数解释和用法与 23.1.3.12 中定义的
Array.prototype.findLastIndex 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 findRec 为 ? FindViaPredicate (O ,
len , descending , predicate ,
thisArg )。
返回 findRec .[[Index]] 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.15 %TypedArray%.prototype.forEach ( callback [
, thisArg ] )
该方法的参数解释和用法与 23.1.3.15 中定义的
Array.prototype.forEach 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
执行 ? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »)。
设置 k 为 k + 1。
返回 undefined 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.16 %TypedArray%.prototype.includes (
searchElement [ , fromIndex ] )
该方法的参数解释和用法与 23.1.3.16 中定义的
Array.prototype.includes 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 len = 0,返回 false 。
令 n 为 ? ToIntegerOrInfinity (fromIndex )。
断言 :如果
fromIndex 为 undefined ,则 n 为 0。
如果 n = +∞,返回 false 。
否则如果 n = -∞,设置 n 为 0。
如果 n ≥ 0,则
令 k 为 n 。
否则,
令 k 为 len + n 。
如果 k < 0,设置 k 为 0。
重复,直到 k < len ,
令 elementK 为 ! Get (O ,
! ToString (𝔽 (k )))。
如果 SameValueZero (searchElement ,
elementK ) 为 true ,返回
true 。
设置 k 为 k + 1。
返回 false 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.17 %TypedArray%.prototype.indexOf (
searchElement [ , fromIndex ] )
该方法的参数解释和用法与 23.1.3.17 中定义的
Array.prototype.indexOf 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 len = 0,返回 -1 𝔽 。
令 n 为 ? ToIntegerOrInfinity (fromIndex )。
断言 :如果
fromIndex 为 undefined ,则 n 为 0。
如果 n = +∞,返回 -1 𝔽 。
否则如果 n = -∞,设置 n 为 0。
如果 n ≥ 0,则
令 k 为 n 。
否则,
令 k 为 len + n 。
如果 k < 0,设置 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ! HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 elementK 为 ! Get (O ,
Pk )。
如果 IsStrictlyEqual (searchElement ,
elementK ) 为 true ,返回 𝔽 (k )。
设置 k 为 k + 1。
返回 -1 𝔽 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.18 %TypedArray%.prototype.join ( separator )
该方法的参数解释和用法与 23.1.3.18 中定义的
Array.prototype.join 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 separator 为 undefined ,令 sep 为
"," 。
否则,令 sep 为 ? ToString (separator )。
令 R 为空字符串。
令 k 为 0。
重复,直到 k < len ,
如果 k > 0,令 R 为 字符串拼接 R 和
sep 的结果。
令 element 为 ! Get (O ,
! ToString (𝔽 (k )))。
如果 element 不为 undefined ,则
令 S 为 ! ToString (element )。
令 R 为 字符串拼接
R 和 S 的结果。
设置 k 为 k + 1。
返回 R 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.19 %TypedArray%.prototype.keys ( )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? ValidateTypedArray (O ,
seq-cst )。
返回 CreateArrayIterator (O ,
key )。
23.2.3.20 %TypedArray%.prototype.lastIndexOf (
searchElement [ , fromIndex ] )
该方法的参数解释和用法与 23.1.3.20 中定义的
Array.prototype.lastIndexOf 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 len = 0,返回 -1 𝔽 。
如果 fromIndex 被传入,令 n 为 ? ToIntegerOrInfinity (fromIndex );否则令
n 为 len - 1。
如果 n = -∞,返回 -1 𝔽 。
如果 n ≥ 0,则
令 k 为 min (n , len -
1)。
否则,
令 k 为 len + n 。
重复,直到 k ≥ 0,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kPresent 为 ! HasProperty (O ,
Pk )。
如果 kPresent 为 true ,则
令 elementK 为 ! Get (O ,
Pk )。
如果 IsStrictlyEqual (searchElement ,
elementK ) 为 true ,返回 𝔽 (k )。
设置 k 为 k - 1。
返回 -1 𝔽 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.21 get %TypedArray%.prototype.length
%TypedArray% .prototype.length
是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[TypedArrayName]] )。
断言 :O 拥有 [[ViewedArrayBuffer]] 和 [[ArrayLength]] 内部槽。
令 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,返回 +0 𝔽 。
令 length 为 TypedArrayLength (taRecord )。
返回 𝔽 (length )。
该函数不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.22 %TypedArray%.prototype.map ( callback [ ,
thisArg ] )
该方法的参数解释和用法与 23.1.3.21 中定义的
Array.prototype.map 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 A 为 ? TypedArraySpeciesCreate (O , «
𝔽 (len ) »)。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
令 mappedValue 为 ? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »)。
执行 ? Set (A , Pk ,
mappedValue , true )。
设置 k 为 k + 1。
返回 A 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.23 %TypedArray%.prototype.reduce ( callback [
, initialValue ] )
该方法的参数解释和用法与 23.1.3.24 中定义的
Array.prototype.reduce 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
如果 len = 0 且未传入 initialValue ,抛出 TypeError
异常。
令 k 为 0。
令 accumulator 为 undefined 。
如果 initialValue 被传入,则
将 accumulator 设为 initialValue 。
否则,
令 Pk 为 ! ToString (𝔽 (k ))。
将 accumulator 设为 ! Get (O , Pk )。
设置 k 为 k + 1。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
将 accumulator 设为 ? Call (callback ,
undefined , « accumulator , kValue ,
𝔽 (k ), O »)。
设置 k 为 k + 1。
返回 accumulator 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.24 %TypedArray%.prototype.reduceRight (
callback [ , initialValue ] )
该方法的参数解释和用法与 23.1.3.25 中定义的
Array.prototype.reduceRight 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
如果 len = 0 且未传入 initialValue ,抛出 TypeError
异常。
令 k 为 len - 1。
令 accumulator 为 undefined 。
如果 initialValue 被传入,则
将 accumulator 设为 initialValue 。
否则,
令 Pk 为 ! ToString (𝔽 (k ))。
将 accumulator 设为 ! Get (O , Pk )。
设置 k 为 k - 1。
重复,直到 k ≥ 0,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
将 accumulator 设为 ? Call (callback ,
undefined , « accumulator , kValue ,
𝔽 (k ), O »)。
设置 k 为 k - 1。
返回 accumulator 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.25 %TypedArray%.prototype.reverse ( )
该方法的参数解释和用法与 23.1.3.26 中定义的
Array.prototype.reverse 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 middle 为 floor (len / 2)。
令 lower 为 0。
重复,直到 lower ≠ middle ,
令 upper 为 len - lower - 1。
令 upperP 为 ! ToString (𝔽 (upper ))。
令 lowerP 为 ! ToString (𝔽 (lower ))。
令 lowerValue 为 ! Get (O ,
lowerP )。
令 upperValue 为 ! Get (O ,
upperP )。
执行 ! Set (O ,
lowerP , upperValue , true )。
执行 ! Set (O ,
upperP , lowerValue , true )。
设置 lower 为 lower + 1。
返回 O 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.26 %TypedArray%.prototype.set ( source [ ,
offset ] )
该方法会在此 TypedArray 中设置多个值,从 source 读取值。具体细节取决于 source 的类型。可选的
offset 值表示在此 TypedArray 中写入值的第一个元素索引。如果省略,假定为 0。
该方法被调用时执行以下步骤:
令 target 为 this 值。
执行 ? RequireInternalSlot (target ,
[[TypedArrayName]] )。
断言 :target 拥有 [[ViewedArrayBuffer]] 内部槽。
令 targetOffset 为 ? ToIntegerOrInfinity (offset )。
如果 targetOffset < 0,抛出 RangeError 异常。
如果 source 是带有 [[TypedArrayName]] 内部槽的 对象 ,则
执行 ? SetTypedArrayFromTypedArray (target ,
targetOffset , source )。
否则,
执行 ? SetTypedArrayFromArrayLike (target ,
targetOffset , source )。
返回 undefined 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.26.1 SetTypedArrayFromTypedArray ( target ,
targetOffset , source )
抽象操作 SetTypedArrayFromTypedArray 接收参数 target (一个 TypedArray )、targetOffset (一个非负
整数 或
+∞)、source (一个 TypedArray ),并返回 正常完成,包含
unused 或 抛出完成 。它会在
target 从索引 targetOffset 开始,读取 source 的值设置多个值。调用时执行以下步骤:
令 targetBuffer 为 target .[[ViewedArrayBuffer]] 。
令 targetRecord 为 MakeTypedArrayWithBufferWitnessRecord (target ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (targetRecord )
为 true ,抛出 TypeError 异常。
令 targetLength 为 TypedArrayLength (targetRecord )。
令 srcBuffer 为 source .[[ViewedArrayBuffer]] 。
令 srcRecord 为 MakeTypedArrayWithBufferWitnessRecord (source ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (srcRecord )
为 true ,抛出 TypeError 异常。
令 srcLength 为 TypedArrayLength (srcRecord )。
令 targetType 为 TypedArrayElementType (target )。
令 targetElementSize 为 TypedArrayElementSize (target )。
令 targetByteOffset 为 target .[[ByteOffset]] 。
令 srcType 为 TypedArrayElementType (source )。
令 srcElementSize 为 TypedArrayElementSize (source )。
令 srcByteOffset 为 source .[[ByteOffset]] 。
如果 targetOffset = +∞,抛出 RangeError 异常。
如果 srcLength + targetOffset >
targetLength ,抛出 RangeError 异常。
如果 target .[[ContentType]] 不等于
source .[[ContentType]] ,抛出
TypeError 异常。
如果 IsSharedArrayBuffer (srcBuffer )
为 true ,IsSharedArrayBuffer (targetBuffer )
为 true ,并且 srcBuffer .[[ArrayBufferData]] 等于 targetBuffer .[[ArrayBufferData]] ,则令 sameSharedArrayBuffer
为 true ;否则,令 sameSharedArrayBuffer 为
false 。
如果 SameValue (srcBuffer ,
targetBuffer ) 为 true 或
sameSharedArrayBuffer 为 true ,则
令 srcByteLength 为 TypedArrayByteLength (srcRecord )。
将 srcBuffer 设为 ? CloneArrayBuffer (srcBuffer ,
srcByteOffset , srcByteLength )。
令 srcByteIndex 为 0。
否则,
令 srcByteIndex 为 srcByteOffset 。
令 targetByteIndex 为 (targetOffset ×
targetElementSize ) + targetByteOffset 。
令 limit 为 targetByteIndex +
(targetElementSize × srcLength )。
如果 srcType 等于 targetType ,则
注:传输操作必须以保持源数据比特级编码的方式执行。
重复,直到 targetByteIndex < limit ,
令 value 为 GetValueFromBuffer (srcBuffer ,
srcByteIndex , uint8 ,
true , unordered )。
执行 SetValueInBuffer (targetBuffer ,
targetByteIndex , uint8 ,
value , true ,
unordered )。
设置 srcByteIndex 为 srcByteIndex + 1。
设置 targetByteIndex 为 targetByteIndex + 1。
否则,
重复,直到 targetByteIndex < limit ,
令 value 为 GetValueFromBuffer (srcBuffer ,
srcByteIndex , srcType ,
true , unordered )。
执行 SetValueInBuffer (targetBuffer ,
targetByteIndex , targetType ,
value , true ,
unordered )。
设置 srcByteIndex 为 srcByteIndex +
srcElementSize 。
设置 targetByteIndex 为 targetByteIndex +
targetElementSize 。
返回 unused 。
23.2.3.26.2 SetTypedArrayFromArrayLike ( target ,
targetOffset , source )
抽象操作 SetTypedArrayFromArrayLike 接收参数 target (一个 TypedArray )、targetOffset (一个非负
整数 或
+∞)、source (一个 ECMAScript
语言值 ,但不是 TypedArray ),并返回 正常完成,包含
unused 或 抛出完成 。它会在
target 从索引 targetOffset 开始,读取 source 的值设置多个值。调用时执行以下步骤:
令 targetRecord 为 MakeTypedArrayWithBufferWitnessRecord (target ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (targetRecord )
为 true ,抛出 TypeError 异常。
令 targetLength 为 TypedArrayLength (targetRecord )。
令 src 为 ? ToObject (source )。
令 srcLength 为 ? LengthOfArrayLike (src )。
如果 targetOffset = +∞,抛出 RangeError 异常。
如果 srcLength + targetOffset >
targetLength ,抛出 RangeError 异常。
令 k 为 0。
重复,直到 k < srcLength ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 value 为 ? Get (src ,
Pk )。
令 targetIndex 为 𝔽 (targetOffset +
k )。
执行 ? TypedArraySetElement (target ,
targetIndex , value )。
设置 k 为 k + 1。
返回 unused 。
23.2.3.27 %TypedArray%.prototype.slice ( start ,
end )
该方法的参数解释和用法与 23.1.3.28 中定义的
Array.prototype.slice 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 srcArrayLength 为 TypedArrayLength (taRecord )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 startIndex 为 0。
否则如果 relativeStart < 0,令 startIndex 为 max (srcArrayLength
+
relativeStart , 0)。
否则,令 startIndex 为 min (relativeStart ,
srcArrayLength )。
如果 end 为 undefined ,令 relativeEnd 为
srcArrayLength ;否则令 relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 endIndex 为 0。
否则如果 relativeEnd < 0,令 endIndex 为 max (srcArrayLength
+
relativeEnd , 0)。
否则,令 endIndex 为 min (relativeEnd ,
srcArrayLength )。
令 countBytes 为 max (endIndex -
startIndex , 0)。
令 A 为 ? TypedArraySpeciesCreate (O , «
𝔽 (countBytes ) »)。
如果 countBytes > 0,则
设置 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,抛出 TypeError 异常。
设置 endIndex 为 min (endIndex , TypedArrayLength (taRecord ))。
设置 countBytes 为 max (endIndex -
startIndex , 0)。
令 srcType 为 TypedArrayElementType (O )。
令 targetType 为 TypedArrayElementType (A )。
如果 srcType 等于 targetType ,则
注:传输操作必须以保持源数据比特级编码的方式执行。
令 srcBuffer 为 O .[[ViewedArrayBuffer]] 。
令 targetBuffer 为 A .[[ViewedArrayBuffer]] 。
令 elementSize 为 TypedArrayElementSize (O )。
令 srcByteOffset 为 O .[[ByteOffset]] 。
令 srcByteIndex 为 (startIndex ×
elementSize ) + srcByteOffset 。
令 targetByteIndex 为 A .[[ByteOffset]] 。
令 endByteIndex 为 targetByteIndex +
(countBytes × elementSize )。
重复,直到 targetByteIndex <
endByteIndex ,
令 value 为 GetValueFromBuffer (srcBuffer ,
srcByteIndex , uint8 ,
true , unordered )。
执行 SetValueInBuffer (targetBuffer ,
targetByteIndex , uint8 ,
value , true ,
unordered )。
设置 srcByteIndex 为 srcByteIndex + 1。
设置 targetByteIndex 为 targetByteIndex
+ 1。
否则,
令 n 为 0。
令 k 为 startIndex 。
重复,直到 k < endIndex ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O ,
Pk )。
执行 ! Set (A ,
! ToString (𝔽 (n )),
kValue , true )。
设置 k 为 k + 1。
设置 n 为 n + 1。
返回 A 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.28 %TypedArray%.prototype.some ( callback [ ,
thisArg ] )
该方法的参数解释和用法与 23.1.3.29 中定义的
Array.prototype.some 相同。
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
令 kValue 为 ! Get (O , Pk )。
令 testResult 为 ToBoolean (? Call (callback ,
thisArg , « kValue , 𝔽 (k ),
O »))。
如果 testResult 为 true ,返回
true 。
设置 k 为 k + 1。
返回 false 。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.29 %TypedArray%.prototype.sort ( comparator )
这是一个不同的方法,除下述说明外,其实现要求与 23.1.3.30 中定义的
Array.prototype.sort 相同。该方法的实现可以利用 this 值是一个具有固定长度且其
整数索引 属性不是稀疏的对象这一事实进行优化。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
该方法被调用时执行以下步骤:
如果 comparator 不为 undefined 且 IsCallable (comparator ) 为
false ,抛出 TypeError 异常。
令 obj 为 this 值。
令 taRecord 为 ? ValidateTypedArray (obj ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
注:以下闭包执行数值比较,而不是 23.1.3.30 中使用的字符串比较。
令 SortCompare 为一个新的 抽象闭包 ,带参数
(x , y ),捕获 comparator 并在调用时执行以下步骤:
返回 ? CompareTypedArrayElements (x ,
y , comparator )。
令 sortedList 为 ? SortIndexedProperties (obj ,
len , SortCompare , read-through-holes )。
令 j 为 0。
重复,直到 j < len ,
执行 ! Set (obj ,
! ToString (𝔽 (j )),
sortedList [j ], true )。
设置 j 为 j + 1。
返回 obj 。
注
由于 NaN 总是大于任何其他值(见 CompareTypedArrayElements ),当
comparator 未提供时,NaN 属性值总是排在结果的末尾。
23.2.3.30 %TypedArray%.prototype.subarray ( start ,
end )
该方法返回一个新的 TypedArray ,其元素类型与此 TypedArray 的元素类型相同,ArrayBuffer 也与此
TypedArray 相同,引用 start (包含)到 end (不包含)区间内的元素。如果
start 或 end 为负数,则它表示从数组末尾开始的索引,而不是从头开始。
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[TypedArrayName]] )。
断言 :
O 拥有 [[ViewedArrayBuffer]] 内部槽。
令 buffer 为 O .[[ViewedArrayBuffer]] 。
令 srcRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (srcRecord )
为 true ,则
令 srcLength 为 0。
否则,
令 srcLength 为 TypedArrayLength (srcRecord )。
令 relativeStart 为 ? ToIntegerOrInfinity (start )。
如果 relativeStart = -∞,令 startIndex 为 0。
否则如果 relativeStart < 0,令 startIndex 为 max (srcLength +
relativeStart , 0)。
否则,令 startIndex 为 min (relativeStart ,
srcLength )。
令 elementSize 为 TypedArrayElementSize (O )。
令 srcByteOffset 为 O .[[ByteOffset]] 。
令 beginByteOffset 为 srcByteOffset + (startIndex
× elementSize )。
如果 O .[[ArrayLength]] 为
auto 且 end 为 undefined ,则
令 argumentsList 为 « buffer , 𝔽 (beginByteOffset ) »。
否则,
如果 end 为 undefined ,令
relativeEnd 为 srcLength ;否则令
relativeEnd 为 ? ToIntegerOrInfinity (end )。
如果 relativeEnd = -∞,令 endIndex 为 0。
否则如果 relativeEnd < 0,令 endIndex 为 max (srcLength +
relativeEnd , 0)。
否则,令 endIndex 为 min (relativeEnd ,
srcLength )。
令 newLength 为 max (endIndex -
startIndex , 0)。
令 argumentsList 为 « buffer , 𝔽 (beginByteOffset ), 𝔽 (newLength ) »。
返回 ? TypedArraySpeciesCreate (O ,
argumentsList )。
该方法不是泛型的。this 值必须是带有 [[TypedArrayName]] 内部槽的对象。
23.2.3.31 %TypedArray%.prototype.toLocaleString ( [
reserved1 [ , reserved2 ] ] )
这是一个不同的方法,其实现算法与 23.1.3.32 中定义的
Array.prototype.toLocaleString 相同,只是用 TypedArrayLength 替换了对
"length" 的 [[Get]] 操作。该算法的实现可以利用
this 值在底层缓冲区不可调整大小时具有固定长度且其 整数索引 属性不是稀疏的事实进行优化。但这种优化不能引入任何可观察的行为变化。
该方法不是泛型的。调用算法前会用 this 值和 seq-cst 作为参数调用 ValidateTypedArray 。如果其结果是 异常完成 ,则抛出该异常而不是执行算法。
注
如果 ECMAScript 实现包含 ECMA-402 国际化 API,则该方法基于 ECMA-402 规范中的
Array.prototype.toLocaleString 算法。
23.2.3.32 %TypedArray%.prototype.toReversed ( )
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 length 为 TypedArrayLength (taRecord )。
令 A 为 ? TypedArrayCreateSameType (O , «
𝔽 (length ) »)。
令 k 为 0。
重复,直到 k < length ,
令 from 为 ! ToString (𝔽 (length -
k - 1))。
令 Pk 为 ! ToString (𝔽 (k ))。
令 fromValue 为 ! Get (O ,
from )。
执行 ! Set (A ,
Pk , fromValue , true )。
设置 k 为 k + 1。
返回 A 。
23.2.3.33 %TypedArray%.prototype.toSorted (
comparator )
该方法被调用时执行以下步骤:
如果 comparator 不为 undefined 且 IsCallable (comparator ) 为
false ,抛出 TypeError 异常。
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 A 为 ? TypedArrayCreateSameType (O , «
𝔽 (len ) »)。
注:以下闭包执行数值比较,而不是 23.1.3.34 中使用的字符串比较。
令 SortCompare 为一个新的 抽象闭包 ,带参数
(x , y ),捕获 comparator 并在调用时执行以下步骤:
返回 ? CompareTypedArrayElements (x ,
y , comparator )。
令 sortedList 为 ? SortIndexedProperties (O ,
len , SortCompare , read-through-holes )。
令 j 为 0。
重复,直到 j < len ,
执行 ! Set (A ,
! ToString (𝔽 (j )),
sortedList [j ], true )。
设置 j 为 j + 1。
返回 A 。
23.2.3.34 %TypedArray%.prototype.toString ( )
"toString" 属性的初始值是 %Array.prototype.toString%,定义见 23.1.3.36 。
23.2.3.35 %TypedArray%.prototype.values ( )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? ValidateTypedArray (O ,
seq-cst )。
返回 CreateArrayIterator (O ,
value )。
23.2.3.36 %TypedArray%.prototype.with ( index ,
value )
该方法被调用时执行以下步骤:
令 O 为 this 值。
令 taRecord 为 ? ValidateTypedArray (O ,
seq-cst )。
令 len 为 TypedArrayLength (taRecord )。
令 relativeIndex 为 ? ToIntegerOrInfinity (index )。
如果 relativeIndex ≥ 0,令 actualIndex 为
relativeIndex 。
否则,令 actualIndex 为 len + relativeIndex 。
如果 O .[[ContentType]] 为
bigint ,令 numericValue 为 ? ToBigInt (value )。
否则,令 numericValue 为 ? ToNumber (value )。
如果 IsValidIntegerIndex (O ,
𝔽 (actualIndex )) 为
false ,抛出 RangeError 异常。
令 A 为 ? TypedArrayCreateSameType (O , «
𝔽 (len ) »)。
令 k 为 0。
重复,直到 k < len ,
令 Pk 为 ! ToString (𝔽 (k ))。
如果 k = actualIndex ,令 fromValue 为
numericValue 。
否则,令 fromValue 为 ! Get (O ,
Pk )。
执行 ! Set (A ,
Pk , fromValue , true )。
设置 k 为 k + 1。
返回 A 。
23.2.3.37 %TypedArray%.prototype [ %Symbol.iterator% ] ( )
%Symbol.iterator% 属性的初始值是
%TypedArray.prototype.values%,定义见 23.2.3.35 。
23.2.3.38 get %TypedArray%.prototype [ %Symbol.toStringTag% ]
%TypedArray% .prototype[%Symbol.toStringTag%]
是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 O 为 this 值。
如果 O 不是对象 ,返回
undefined 。
如果 O 没有 [[TypedArrayName]] 内部槽,返回
undefined 。
令 name 为 O .[[TypedArrayName]] 。
断言 :
name 是字符串 。
返回 name 。
该属性具有属性 { [[Enumerable]] :
false , [[Configurable]] : true
}。
该函数的 "name" 属性的初始值为 "get
[Symbol.toStringTag]" 。
23.2.4 TypedArray 对象的抽象操作
23.2.4.1 TypedArraySpeciesCreate ( exemplar ,
argumentList )
抽象操作 TypedArraySpeciesCreate 接收参数 exemplar (一个 TypedArray )和
argumentList (一个 List ,元素为 ECMAScript 语言值 ),返回 正常完成,包含 一个 TypedArray 或
抛出完成 。它用于指定用从
exemplar 派生的 构造函数 创建新的 TypedArray 。与 ArraySpeciesCreate 可以通过 %Symbol.species% 创建非数组对象不同,此操作强制要求该
构造函数
必须创建实际的 TypedArray 。调用时执行以下步骤:
令 defaultConstructor 为 表 75 中与
exemplar .[[TypedArrayName]] 同名的内建对象。
令 constructor 为 ? SpeciesConstructor (exemplar ,
defaultConstructor )。
令 result 为 ? TypedArrayCreateFromConstructor (constructor ,
argumentList )。
断言 :
result 拥有 [[TypedArrayName]] 和 [[ContentType]] 内部槽。
如果 result .[[ContentType]] 不等于
exemplar .[[ContentType]] ,抛出
TypeError 异常。
返回 result 。
23.2.4.2 TypedArrayCreateFromConstructor (
constructor , argumentList )
抽象操作 TypedArrayCreateFromConstructor 接收参数 constructor (一个 构造函数 )和
argumentList (一个 List ,元素为ECMAScript 语言值 ),返回 正常完成,包含 一个 TypedArray 或
抛出完成 。它用于指定用
构造函数
创建新的 TypedArray 。调用时执行以下步骤:
令 newTypedArray 为 ? Construct (constructor ,
argumentList )。
令 taRecord 为 ? ValidateTypedArray (newTypedArray ,
seq-cst )。
如果 argumentList 的元素数量为 1 且 argumentList [0] 是数字 ,则
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,抛出 TypeError 异常。
令 length 为 TypedArrayLength (taRecord )。
如果 length < ℝ (argumentList [0]),抛出
TypeError 异常。
返回 newTypedArray 。
23.2.4.3 TypedArrayCreateSameType ( exemplar ,
argumentList )
抽象操作 TypedArrayCreateSameType 接收参数 exemplar (一个 TypedArray )和
argumentList (一个 List ,元素为ECMAScript 语言值 ),返回 正常完成,包含 一个 TypedArray 或
抛出完成 。它用于指定用从
exemplar 派生的 构造函数 创建新的 TypedArray 。与 TypedArraySpeciesCreate 能通过
%Symbol.species% 构造自定义 TypedArray
子类不同,此操作始终使用内建 TypedArray 构造函数 。调用时执行以下步骤:
令 constructor 为 表 75
中与 exemplar .[[TypedArrayName]] 同名的内建对象。
令 result 为 ? TypedArrayCreateFromConstructor (constructor ,
argumentList )。
断言 :
result 拥有 [[TypedArrayName]] 和 [[ContentType]] 内部槽。
断言 :
result .[[ContentType]] 等于
exemplar .[[ContentType]] 。
返回 result 。
23.2.4.4 ValidateTypedArray ( O , order )
抽象操作 ValidateTypedArray 接收参数 O (一个 ECMAScript 语言值 )和
order (seq-cst 或 unordered ),返回
正常完成,包含 一个 TypedArray
带缓冲区见证记录 或 抛出完成 。调用时执行以下步骤:
执行 ? RequireInternalSlot (O ,
[[TypedArrayName]] )。
断言 :
O 拥有 [[ViewedArrayBuffer]] 内部槽。
令 taRecord 为 MakeTypedArrayWithBufferWitnessRecord (O ,
order )。
如果 IsTypedArrayOutOfBounds (taRecord )
为 true ,抛出 TypeError 异常。
返回 taRecord 。
23.2.4.5 TypedArrayElementSize ( O )
抽象操作 TypedArrayElementSize 接收参数 O (一个 TypedArray ),返回一个非负整数 。调用时执行以下步骤:
返回 表 75 中
O .[[TypedArrayName]] 指定的元素大小值。
23.2.4.6 TypedArrayElementType ( O )
抽象操作 TypedArrayElementType 接收参数 O (一个 TypedArray ),返回 TypedArray 元素类型 。调用时执行以下步骤:
返回 表 75 中
O .[[TypedArrayName]] 指定的元素类型值。
23.2.4.7 CompareTypedArrayElements ( x , y ,
comparator )
抽象操作 CompareTypedArrayElements 接收参数 x (一个 Number 或 BigInt)、y (一个 Number 或
BigInt)、comparator (一个 函数对象 或 undefined ),返回
正常完成,包含 一个 Number 或
异常完成 。调用时执行以下步骤:
断言 :
x 是
Number 且 y 是 Number ,或者
x 是
BigInt
且 y 是
BigInt 。
如果 comparator 不为 undefined ,则
令 v 为 ? ToNumber (?
Call (comparator ,
undefined , « x , y »))。
如果 v 为 NaN ,返回
+0 𝔽 。
返回 v 。
如果 x 和 y 都是 NaN ,返回
+0 𝔽 。
如果 x 是 NaN ,返回 1 𝔽 。
如果 y 是 NaN ,返回 -1 𝔽 。
如果 x < y ,返回 -1 𝔽 。
如果 x > y ,返回 1 𝔽 。
如果 x 是 -0 𝔽 且 y 是
+0 𝔽 ,返回 -1 𝔽 。
如果 x 是 +0 𝔽 且 y 是
-0 𝔽 ,返回 1 𝔽 。
返回 +0 𝔽 。
注
这执行的是数值比较,而不是
23.1.3.30.2 中的字符串比较。
23.2.5 TypedArray 构造函数
每个 TypedArray 构造函数 :
是一个内建对象,结构如下所述,唯一的区别是 构造函数 名称不同于 TypedArray ,见 表 75 。
是一个函数,其行为会根据参数的数量和类型而异。对 TypedArray 的实际调用行为取决于传递给它的参数数量和类型。
不应作为普通函数调用,否则会抛出异常。
可以用作类定义的 extends 子句的值。想要继承指定 TypedArray 行为的子类 构造函数 必须包含对
TypedArray 构造函数 的 super
调用,以用必要的内部状态创建和初始化子类实例,以支持 %TypedArray% .prototype
内建方法。
23.2.5.1 TypedArray ( ...args )
每个 TypedArray 构造函数 被调用时执行以下步骤:
如果 NewTarget 为 undefined ,抛出 TypeError 异常。
令 constructorName 为 表 75
中为此 TypedArray 构造函数 指定的 构造函数 名称的字符串值。
令 proto 为 "%TypedArray .prototype%"。
令 numberOfArgs 为 args 的元素数量。
如果 numberOfArgs = 0,则
返回 ? AllocateTypedArray (constructorName ,
NewTarget, proto , 0)。
否则,
令 firstArgument 为 args [0]。
如果 firstArgument 是对象 ,则
令 O 为 ? AllocateTypedArray (constructorName ,
NewTarget, proto )。
如果 firstArgument 有 [[TypedArrayName]] 内部槽,则
执行 ? InitializeTypedArrayFromTypedArray (O ,
firstArgument )。
否则如果 firstArgument 有 [[ArrayBufferData]] 内部槽,则
如果 numberOfArgs > 1,令 byteOffset 为
args [1];否则令 byteOffset 为
undefined 。
如果 numberOfArgs > 2,令 length 为
args [2];否则令 length 为
undefined 。
执行 ? InitializeTypedArrayFromArrayBuffer (O ,
firstArgument , byteOffset ,
length )。
否则,
断言 :
firstArgument 是对象 且
firstArgument
没有 [[TypedArrayName]] 或 [[ArrayBufferData]] 内部槽。
令 usingIterator 为 ? GetMethod (firstArgument ,
%Symbol.iterator% )。
如果 usingIterator 不为
undefined ,则
令 values 为 ? IteratorToList (?
GetIteratorFromMethod (firstArgument ,
usingIterator ))。
执行 ? InitializeTypedArrayFromList (O ,
values )。
否则,
注:firstArgument 不是 可迭代对象 ,所以假定它已经是
类数组对象 。
执行 ? InitializeTypedArrayFromArrayLike (O ,
firstArgument )。
返回 O 。
否则,
断言 :
firstArgument 不是对象 。
令 elementLength 为 ? ToIndex (firstArgument )。
返回 ? AllocateTypedArray (constructorName ,
NewTarget, proto , elementLength )。
23.2.5.1.1 AllocateTypedArray ( constructorName ,
newTarget , defaultProto [ , length ] )
抽象操作 AllocateTypedArray 接收参数 constructorName (一个字符串,为 TypedArray
构造函数 名称,见 表
75 ),newTarget (一个 构造函数 ),defaultProto (一个字符串),可选参数
length (一个非负整数 ),返回 正常完成,包含 一个
TypedArray 或 抛出完成 。用于校验并创建
TypedArray 构造函数 的实例。如果传入了
length ,还会分配一个相应长度的 ArrayBuffer,并与新的 TypedArray
实例关联。AllocateTypedArray 提供了 TypedArray 共享的通用语义。调用时执行以下步骤:
令 proto 为 ? GetPrototypeFromConstructor (newTarget ,
defaultProto )。
令 obj 为 TypedArrayCreate (proto )。
断言 :obj .[[ViewedArrayBuffer]] 为 undefined 。
设置 obj .[[TypedArrayName]] 为
constructorName 。
如果 constructorName 是 "BigInt64Array" 或
"BigUint64Array" ,将 obj .[[ContentType]] 设为 bigint 。
否则,将 obj .[[ContentType]] 设为
number 。
如果未传入 length ,则
设置 obj .[[ByteLength]] 为 0。
设置 obj .[[ByteOffset]] 为 0。
设置 obj .[[ArrayLength]] 为 0。
否则,
执行 ? AllocateTypedArrayBuffer (obj ,
length )。
返回 obj 。
23.2.5.1.2 InitializeTypedArrayFromTypedArray (
O , srcArray )
抽象操作 InitializeTypedArrayFromTypedArray 接收参数 O (一个 TypedArray )和
srcArray (一个 TypedArray ),返回 正常完成,包含
unused 或 抛出完成 。调用时执行以下步骤:
令 srcData 为 srcArray .[[ViewedArrayBuffer]] 。
令 elementType 为 TypedArrayElementType (O )。
令 elementSize 为 TypedArrayElementSize (O )。
令 srcType 为 TypedArrayElementType (srcArray )。
令 srcElementSize 为 TypedArrayElementSize (srcArray )。
令 srcByteOffset 为 srcArray .[[ByteOffset]] 。
令 srcRecord 为 MakeTypedArrayWithBufferWitnessRecord (srcArray ,
seq-cst )。
如果 IsTypedArrayOutOfBounds (srcRecord )
为 true ,抛出 TypeError 异常。
令 elementLength 为 TypedArrayLength (srcRecord )。
令 byteLength 为 elementSize × elementLength 。
如果 elementType 等于 srcType ,则
令 data 为 ? CloneArrayBuffer (srcData ,
srcByteOffset , byteLength )。
否则,
令 data 为 ? AllocateArrayBuffer (%ArrayBuffer% ,
byteLength )。
如果 srcArray .[[ContentType]] 不等于
O .[[ContentType]] ,抛出
TypeError 异常。
令 srcByteIndex 为 srcByteOffset 。
令 targetByteIndex 为 0。
令 count 为 elementLength 。
重复,直到 count > 0,
令 value 为 GetValueFromBuffer (srcData ,
srcByteIndex , srcType ,
true , unordered )。
执行 SetValueInBuffer (data ,
targetByteIndex , elementType ,
value , true ,
unordered )。
设置 srcByteIndex 为 srcByteIndex +
srcElementSize 。
设置 targetByteIndex 为 targetByteIndex +
elementSize 。
设置 count 为 count - 1。
设置 O .[[ViewedArrayBuffer]] 为
data 。
设置 O .[[ByteLength]] 为
byteLength 。
设置 O .[[ByteOffset]] 为 0。
设置 O .[[ArrayLength]] 为
elementLength 。
返回 unused 。
23.2.6 TypedArray 构造函数的属性
每个 TypedArray 构造函数 :
拥有一个 [[Prototype]] 内部槽,其值为 %TypedArray% 。
有一个 "length" 属性,其值为 3 𝔽 。
有一个 "name" 属性,其值为 构造函数 在 表 75 中为其指定的字符串值。
拥有以下属性:
23.2.6.1 TypedArray .BYTES_PER_ELEMENT
TypedArray .BYTES_PER_ELEMENT 的值为 表 75 中为
TypedArray 指定的元素大小值。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
23.2.6.2 TypedArray .prototype
TypedArray .prototype 的初始值为对应的 TypedArray 原型内建对象(23.2.7 )。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
23.2.7 TypedArray 原型对象的属性
每个 TypedArray 原型对象:
23.2.7.1 TypedArray .prototype.BYTES_PER_ELEMENT
TypedArray .prototype.BYTES_PER_ELEMENT 的值为 表 75 中为
TypedArray 指定的元素大小值。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
23.2.7.2 TypedArray .prototype.constructor
某给定 TypedArray 构造函数 的原型的 "constructor"
属性的初始值为该 构造函数 本身。
23.2.8 TypedArray 实例的属性
TypedArray 实例是 TypedArrays 。每个 TypedArray 实例继承自对应的
TypedArray 原型对象。每个 TypedArray 实例都有如下内部槽:[[TypedArrayName]] 、[[ViewedArrayBuffer]] 、[[ByteLength]] 、[[ByteOffset]] 和 [[ArrayLength]] 。
24 键控集合
24.1 Map 对象
Map 是一种键/值对集合,其中键和值都可以是任意的 ECMAScript 语言值 。在 Map
的集合中,每个不同的键值只能出现在一个键/值对中。不同的键值通过 SameValueZero 比较算法进行区分。
Map 必须通过哈希表或其他机制实现,这些机制平均而言可以提供次线性的元素访问时间。本规范中所用的数据结构仅用于描述 Map 所需的可观察语义,而不是可行的实现模型。
24.1.1 Map 构造函数
Map 构造函数 :
即 %Map% 。
是 全局对象 的 "Map" 属性的初始值。
作为 构造函数
调用时会创建并初始化一个新的 Map。
不应作为普通函数调用,否则会抛出异常。
可以用作类定义的 extends 子句的值。想要继承指定 Map 行为的子类 构造函数 必须包含对 Map 构造函数 的
super 调用,以用必要的内部状态创建和初始化子类实例,以支持 Map.prototype 内建方法。
24.1.1.1 Map ( [ iterable ] )
该函数被调用时执行以下步骤:
如果 NewTarget 为 undefined ,抛出 TypeError 异常。
令 map 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%Map.prototype%" , « [[MapData]] »)。
设置 map .[[MapData]] 为一个新的空 List 。
如果 iterable 为 undefined 或 null ,返回
map 。
令 adder 为 ? Get (map ,
"set" )。
如果 IsCallable (adder ) 为
false ,抛出 TypeError 异常。
返回 ? AddEntriesFromIterable (map ,
iterable , adder )。
注
如果参数 iterable 存在,期望它是一个实现了 %Symbol.iterator%
方法的对象,该方法返回一个 迭代器对象 ,它会生成一个包含两个元素的 类数组对象 ,第一个元素将用作 Map
的键,第二个元素作为与该键关联的值。
24.1.1.2 AddEntriesFromIterable ( target ,
iterable , adder )
抽象操作 AddEntriesFromIterable 接收参数 target (一个对象)、iterable (ECMAScript 语言值 ,但不是
undefined 或 null )、adder (一个 函数对象 ),返回 正常完成,包含 一个 ECMAScript 语言值 或 抛出完成 。adder
调用时其接收者为 target 。调用时执行以下步骤:
令 iteratorRecord 为 ? GetIterator (iterable ,
sync )。
重复,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 为 done ,返回 target 。
如果 next 不是对象 ,则
令 error 为 ThrowCompletion (一个新创建的
TypeError 对象)。
返回 ? IteratorClose (iteratorRecord ,
error )。
令 k 为 Completion (Get (next ,
"0" ))。
IfAbruptCloseIterator (k ,
iteratorRecord )。
令 v 为 Completion (Get (next ,
"1" ))。
IfAbruptCloseIterator (v ,
iteratorRecord )。
令 status 为 Completion (Call (adder ,
target , « k , v »))。
IfAbruptCloseIterator (status ,
iteratorRecord )。
注
参数 iterable 期望是一个实现了 %Symbol.iterator%
方法的对象,该方法返回一个 迭代器对象 ,它会生成一个包含两个元素的 类数组对象 ,第一个元素用作 Map
的键,第二个元素作为与该键关联的值。
24.1.2 Map 构造函数的属性
Map 构造函数 :
24.1.2.1 Map.groupBy ( items , callback )
注
callback 应该是一个接受两个参数的函数。groupBy 会按照升序对 items
中的每个元素调用 callback 一次,并构造一个新的 Map。每个 callback 返回的值会作为 Map
的键。对于每个这样的键,结果 Map 有一个键为该键、值为包含所有 callback 返回该键的元素的数组的条目。
callback 的两个参数分别是元素的值和索引。
groupBy 的返回值是一个 Map。
该函数被调用时执行以下步骤:
令 groups 为 ? GroupBy (items ,
callback , collection )。
令 map 为 ! Construct (%Map% )。
对于 groups 中的每个 Record { [[Key]] , [[Elements]] }
g ,执行
令 elements 为 CreateArrayFromList (g .[[Elements]] )。
令 entry 为 Record
{ [[Key]] : g .[[Key]] , [[Value]] :
elements }。
将 entry 添加到 map .[[MapData]] 。
返回 map 。
24.1.2.2 Map.prototype
Map.prototype 的初始值为 Map
原型对象 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
24.1.2.3 get Map [ %Symbol.species% ]
Map[%Symbol.species%] 是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
返回 this 值。
该函数的 "name" 属性的值为 "get [Symbol.species]" 。
注
创建派生集合对象的方法应当调用 %Symbol.species% 以确定用于创建派生对象的
构造函数 。子类 构造函数 可以重写 %Symbol.species% 以更改默认的
构造函数 分配。
24.1.3 Map 原型对象的属性
Map 原型对象 :
24.1.3.1 Map.prototype.clear ( )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
对于 M .[[MapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
将 p .[[Key]] 设为
empty 。
将 p .[[Value]] 设为
empty 。
返回 undefined 。
注
现有的 [[MapData]] List
会被保留,因为可能存在正在遍历该 List 的
Map 迭代器对象 。
24.1.3.2 Map.prototype.constructor
Map.prototype.constructor 的初始值为 %Map% 。
24.1.3.3 Map.prototype.delete ( key )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
将 key 设为 CanonicalizeKeyedCollectionKey (key )。
对于 M .[[MapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为 true ,则
将 p .[[Key]] 设为
empty 。
将 p .[[Value]] 设为
empty 。
返回 true 。
返回 false 。
注
empty 作为规范设备用来表示一个条目已被删除。实际实现可能会采取其他操作,比如在内部数据结构中物理删除该条目。
24.1.3.4 Map.prototype.entries ( )
该方法被调用时执行以下步骤:
令 M 为 this 值。
返回 ? CreateMapIterator (M ,
key+value )。
24.1.3.5 Map.prototype.forEach ( callback [ ,
thisArg ] )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 entries 为 M .[[MapData]] 。
令 numEntries 为 entries 的元素个数。
令 index 为 0。
重复,直到 index < numEntries ,
令 e 为 entries [index ]。
设置 index 为 index + 1。
如果 e .[[Key]] 不为
empty ,则
执行 ? Call (callback ,
thisArg , « e .[[Value]] , e .[[Key]] , M »)。
注:在 callback 执行期间 entries 的元素数量可能增加。
设置 numEntries 为 entries 的当前元素数量。
返回 undefined 。
注
callback 应该是一个接受三个参数的函数。forEach 会按照键的插入顺序对 Map 中每个键/值对调用
callback 一次。只有实际存在的 Map 键才会被调用 callback ;已被删除的键不会被调用。
如果提供了 thisArg 参数,则该参数会作为每次调用 callback 时的
this 值。如果未提供,则使用 undefined 。
callback 的三个参数分别是项的值、项的键,以及被遍历的 Map。
forEach 本身不会直接修改被调用对象,但该对象可能会被 callback 的调用修改。map 的 [[MapData]] 的每个条目只会被访问一次。在 forEach
开始后添加的新键会被访问。如果某个键被访问后被删除并在 forEach 完成前重新添加,则该键会被再次访问。在
forEach 开始后但被访问前被删除的键不会被访问,除非该键在 forEach 完成前被再次添加。
24.1.3.6 Map.prototype.get ( key )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
将 key 设为 CanonicalizeKeyedCollectionKey (key )。
对于 M .[[MapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为
true ,返回 p .[[Value]] 。
返回 undefined 。
24.1.3.7 Map.prototype.has ( key )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
将 key 设为 CanonicalizeKeyedCollectionKey (key )。
对于 M .[[MapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为
true ,返回 true 。
返回 false 。
24.1.3.8 Map.prototype.keys ( )
该方法被调用时执行以下步骤:
令 M 为 this 值。
返回 ? CreateMapIterator (M ,
key )。
24.1.3.9 Map.prototype.set ( key , value )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
将 key 设为 CanonicalizeKeyedCollectionKey (key )。
对于 M .[[MapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为 true ,则
将 p .[[Value]] 设为
value 。
返回 M 。
令 p 为 Record { [[Key]] : key , [[Value]] :
value }。
将 p 添加到 M .[[MapData]] 。
返回 M 。
24.1.3.10 get Map.prototype.size
Map.prototype.size 是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[MapData]] )。
令 count 为 0。
对于 M .[[MapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty ,则将 count 设为 count + 1。
返回 𝔽 (count )。
24.1.3.11 Map.prototype.values ( )
该方法被调用时执行以下步骤:
令 M 为 this 值。
返回 ? CreateMapIterator (M ,
value )。
24.1.3.12 Map.prototype [ %Symbol.iterator% ] ( )
%Symbol.iterator% 属性的初始值为
%Map.prototype.entries%,定义见 24.1.3.4 。
24.1.3.13 Map.prototype [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"Map" 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
24.1.4 Map 实例的属性
Map 实例是 普通对象 ,它们继承自 Map 原型的属性。Map 实例还拥有 [[MapData]] 内部槽。
24.1.5 Map 迭代器对象
Map
迭代器 是一个表示对某个特定 Map 实例对象的特定遍历的对象。Map 迭代器对象没有具名的 构造函数 。相反,Map 迭代器对象是通过调用 Map
实例对象的某些方法创建的。
24.1.5.1 CreateMapIterator ( map , kind )
抽象操作 CreateMapIterator 接收参数 map (一个 ECMAScript 语言值 )和
kind (key+value 、key 或
value ),返回 正常完成,包含 一个生成器,或
抛出完成 。用于为返回此类
迭代器 的 Map 方法创建 迭代器对象 。调用时执行以下步骤:
执行 ? RequireInternalSlot (map ,
[[MapData]] )。
令 closure 为一个新的 抽象闭包 ,无参数,捕获 map 和
kind ,调用时执行以下步骤:
令 entries 为 map .[[MapData]] 。
令 index 为 0。
令 numEntries 为 entries 的元素数量。
重复,直到 index < numEntries ,
令 e 为 entries [index ]。
设置 index 为 index + 1。
如果 e .[[Key]] 不为
empty ,则
如果 kind 是 key ,则
令 result 为 e .[[Key]] 。
否则如果 kind 是 value ,则
令 result 为 e .[[Value]] 。
否则,
断言 :kind
是 key+value 。
令 result 为 CreateArrayFromList («
e .[[Key]] ,
e .[[Value]] »)。
执行 ? GeneratorYield (CreateIteratorResultObject (result ,
false ))。
注:在 GeneratorYield
挂起本抽象操作执行期间,entries 的元素数量可能增加。
设置 numEntries 为 entries 的元素数量。
返回 undefined 。
返回 CreateIteratorFromClosure (closure ,
"%MapIteratorPrototype%" , %MapIteratorPrototype% )。
24.1.5.2 %MapIteratorPrototype% 对象
%MapIteratorPrototype% 对象:
24.1.5.2.1 %MapIteratorPrototype%.next ( )
返回 ? GeneratorResume (this
值, empty ,
"%MapIteratorPrototype%" )。
24.1.5.2.2 %MapIteratorPrototype% [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"Map Iterator" 。
该属性具有特性 { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
true }.
24.2 Set 对象
Set 对象是 ECMAScript 语言值 的集合。在 Set
的集合中,每个不同的值只能出现一次。不同的值通过 SameValueZero 比较算法进行区分。
Set 对象必须通过哈希表或其他机制实现,这些机制在平均情况下能提供次线性的元素访问时间。本规范中所用的数据结构仅用于描述 Set 对象所需的可观察语义,而非实际的实现模型。
24.2.1 Set 对象的抽象操作
24.2.1.1 Set 记录
Set 记录 是一个 Record 值,用于封装 Set
或类似对象的接口。
Set 记录具有 表 76 中列出的字段。
表 76: Set 记录 字段
字段名
值
含义
[[SetObject]]
一个对象
该 Set 或类似对象。
[[Size]]
一个非负的 整数 或 +∞
该对象报告的大小。
[[Has]]
一个 函数对象
该对象的 has 方法。
[[Keys]]
一个 函数对象
该对象的 keys 方法。
24.2.1.2 GetSetRecord ( obj )
抽象操作 GetSetRecord 接收参数 obj (一个 ECMAScript
语言值 ),返回 正常完成,包含 一个 Set 记录
或 抛出完成 。调用时执行以下步骤:
如果 obj 不是对象 ,抛出 TypeError
异常。
令 rawSize 为 ? Get (obj ,
"size" )。
令 numSize 为 ? ToNumber (rawSize )。
注:如果 rawSize 为 undefined ,则 numSize 会是
NaN 。
如果 numSize 为 NaN ,抛出 TypeError 异常。
令 intSize 为 ! ToIntegerOrInfinity (numSize )。
如果 intSize < 0,抛出 RangeError 异常。
令 has 为 ? Get (obj ,
"has" )。
如果 IsCallable (has ) 为
false ,抛出 TypeError 异常。
令 keys 为 ? Get (obj ,
"keys" )。
如果 IsCallable (keys ) 为
false ,抛出 TypeError 异常。
返回一个新的 Set 记录 { [[SetObject]] : obj , [[Size]] : intSize , [[Has]] : has , [[Keys]] :
keys }。
24.2.1.3 SetDataHas ( setData , value )
抽象操作 SetDataHas 接收参数 setData (一个 List ,元素为 ECMAScript 语言值 或
empty )和 value (一个 ECMAScript
语言值 ),返回一个布尔值。调用时执行以下步骤:
如果 SetDataIndex (setData ,
value ) 为 not-found ,返回 false 。
返回 true 。
24.2.1.4 SetDataIndex ( setData , value )
抽象操作 SetDataIndex 接收参数 setData (一个 List ,元素为 ECMAScript 语言值 或
empty )和 value (一个 ECMAScript 语言值 ),返回一个非负的
整数 或
not-found 。调用时执行以下步骤:
将 value 设为 CanonicalizeKeyedCollectionKey (value )。
令 size 为 setData 的元素数量。
令 index 为 0。
重复,直到 index < size ,
令 e 为 setData [index ]。
如果 e 不为 empty 且 e 等于
value ,则
返回 index 。
将 index 设为 index + 1。
返回 not-found 。
24.2.1.5 SetDataSize ( setData )
抽象操作 SetDataSize 接收参数 setData (一个 List ,元素为 ECMAScript 语言值 或
empty ),返回一个非负 整数 。调用时执行以下步骤:
令 count 为 0。
对于 setData 的每个元素 e ,执行
如果 e 不为 empty ,将 count 设为
count + 1。
返回 count 。
24.2.2 Set 构造函数
Set 构造函数 :
即 %Set% 。
是 全局对象 的 "Set" 属性的初始值。
作为 构造函数
调用时会创建并初始化一个新的 Set 对象。
不应作为普通函数调用,否则会抛出异常。
可以用作类定义的 extends 子句的值。想要继承指定 Set 行为的子类 构造函数 必须包含对 Set 构造函数 的
super 调用,以用必要的内部状态创建和初始化子类实例,以支持 Set.prototype 内建方法。
24.2.2.1 Set ( [ iterable ] )
该函数被调用时执行以下步骤:
如果 NewTarget 为 undefined ,抛出 TypeError 异常。
令 set 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%Set.prototype%" , « [[SetData]] »)。
设置 set .[[SetData]] 为一个新的空 List 。
如果 iterable 为 undefined 或 null ,返回
set 。
令 adder 为 ? Get (set ,
"add" )。
如果 IsCallable (adder ) 为
false ,抛出 TypeError 异常。
令 iteratorRecord 为 ? GetIterator (iterable ,
sync )。
重复,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 为 done ,返回 set 。
令 status 为 Completion (Call (adder ,
set , « next »))。
IfAbruptCloseIterator (status ,
iteratorRecord )。
24.2.3 Set 构造函数的属性
Set 构造函数 :
24.2.3.1 Set.prototype
Set.prototype 的初始值为 Set
原型对象 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
24.2.3.2 get Set [ %Symbol.species% ]
Set[%Symbol.species%] 是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
返回 this 值。
该函数的 "name" 属性值为 "get [Symbol.species]" 。
注
创建派生集合对象的方法应当调用 %Symbol.species% 以确定用于创建派生对象的
构造函数 。子类 构造函数 可以重写 %Symbol.species% 以更改默认的
构造函数 分配。
24.2.4 Set 原型对象的属性
Set 原型对象 :
24.2.4.1 Set.prototype.add ( value )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[SetData]] ).
将 value 设为 CanonicalizeKeyedCollectionKey (value )。
对于 S .[[SetData]] 的每个元素 e ,执行
如果 e 不为 empty 且 SameValue (e ,
value ) 为 true ,则
返回 S 。
将 value 添加到 S .[[SetData]] 。
返回 S 。
24.2.4.2 Set.prototype.clear ( )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[SetData]] ).
对于 S .[[SetData]] 的每个元素 e ,执行
将 S .[[SetData]] 中值为 e
的元素替换为值为 empty 的元素。
返回 undefined 。
注
现有的 [[SetData]] List
会被保留,因为可能存在正在遍历该 List 的
Set 迭代器对象 。
24.2.4.3 Set.prototype.constructor
Set.prototype.constructor 的初始值为 %Set% 。
24.2.4.4 Set.prototype.delete ( value )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[SetData]] ).
将 value 设为 CanonicalizeKeyedCollectionKey (value )。
对于 S .[[SetData]] 的每个元素 e ,执行
如果 e 不为 empty 且 SameValue (e ,
value ) 为 true ,则
将 S .[[SetData]] 中值为 e
的元素替换为值为 empty 的元素。
返回 true 。
返回 false 。
注
empty 作为规范设备用来表示一个条目已被删除。实际实现可能会采取其他操作,比如在内部数据结构中物理删除该条目。
24.2.4.5 Set.prototype.difference ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] ).
令 otherRec 为 ? GetSetRecord (other )。
令 resultSetData 为 O .[[SetData]]
的一个副本。
如果 SetDataSize (O .[[SetData]] ) ≤ otherRec .[[Size]] ,则
令 thisSize 为 O .[[SetData]]
的元素数量。
令 index 为 0。
重复,直到 index < thisSize ,
令 e 为 resultSetData [index ]。
如果 e 不为 empty ,则
令 inOther 为 ToBoolean (?
Call (otherRec .[[Has]] , otherRec .[[SetObject]] , «
e »))。
如果 inOther 为 true ,则
将 resultSetData [index ] 设为
empty 。
将 index 设为 index + 1。
否则,
令 keysIter 为 ? GetIteratorFromMethod (otherRec .[[SetObject]] , otherRec .[[Keys]] )。
令 next 为 not-started 。
重复,直到 next 不为 done ,
将 next 设为 ? IteratorStepValue (keysIter )。
如果 next 不为 done ,则
将 next 设为 CanonicalizeKeyedCollectionKey (next )。
令 valueIndex 为 SetDataIndex (resultSetData ,
next )。
如果 valueIndex 不为
not-found ,则
将 resultSetData [valueIndex ] 设为
empty 。
令 result 为 OrdinaryObjectCreate (%Set.prototype% ,
« [[SetData]] »)。
设置 result .[[SetData]] 为
resultSetData 。
返回 result 。
24.2.4.6 Set.prototype.entries ( )
该方法被调用时执行以下步骤:
令 S 为 this 值。
返回 ? CreateSetIterator (S ,
key+value )。
注
对于遍历目的,Set 类似于每个条目的键和值都相同的 Map。
24.2.4.7 Set.prototype.forEach ( callback [ ,
thisArg ] )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[SetData]] )。
如果 IsCallable (callback ) 为
false ,抛出 TypeError 异常。
令 entries 为 S .[[SetData]] 。
令 numEntries 为 entries 的元素数量。
令 index 为 0。
重复,直到 index < numEntries ,
令 e 为 entries [index ]。
设置 index 为 index + 1。
如果 e 不为 empty ,则
执行 ? Call (callback ,
thisArg , « e , e ,
S »)。
注:在 callback 执行期间 entries 的数量可能增加。
设置 numEntries 为 entries 的当前元素数量。
返回 undefined 。
注
callback 应该是一个接受三个参数的函数。forEach 会按照值插入顺序对 Set 对象中每个存在的值调用
callback 一次。只有实际存在的 Set 值才会被调用 callback ;已被删除的键不会被调用。
如果提供了 thisArg 参数,则其会用作每次调用 callback 时的 this
值。如果未提供,则使用 undefined 。
callback 会被传入三个参数:前两个参数是 Set 中包含的同一个值,第三个参数是正在遍历的 Set 对象。
回调函数采用三个参数是为了与 Map 和 Array 的 forEach 方法的回调一致。对于 Set,每个元素既视为键又视为值。
forEach 本身不会直接修改被调用对象,但该对象可能会被 callback 的调用修改。
每个值通常只会被访问一次。不过,如果某个值被访问后被删除并在 forEach 完成前重新添加,则该值会被再次访问。在
forEach 开始后但被访问前被删除的值不会被访问,除非该值在 forEach 完成前被再次添加。在
forEach 开始后添加的新值会被访问。
24.2.4.8 Set.prototype.has ( value )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[SetData]] )。
将 value 设为 CanonicalizeKeyedCollectionKey (value )。
对于 S .[[SetData]] 的每个元素 e ,执行
如果 e 不为 empty 且 SameValue (e ,
value ) 为 true ,返回 true 。
返回 false 。
24.2.4.9 Set.prototype.intersection ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] )。
令 otherRec 为 ? GetSetRecord (other )。
令 resultSetData 为一个新的空 List 。
如果 SetDataSize (O .[[SetData]] ) ≤ otherRec .[[Size]] ,则
令 thisSize 为 O .[[SetData]]
的元素数量。
令 index 为 0。
重复,直到 index < thisSize ,
令 e 为 O .[[SetData]] [index ]。
设置 index 为 index + 1。
如果 e 不为 empty ,则
令 inOther 为 ToBoolean (?
Call (otherRec .[[Has]] , otherRec .[[SetObject]] , «
e »))。
如果 inOther 为 true ,则
注:较早对 otherRec .[[Has]] 的调用可能会移除并重新添加
O .[[SetData]]
的元素,这可能导致同一元素在本遍历中被访问两次。
如果 SetDataHas (resultSetData ,
e ) 为 false ,则
将 e 添加到 resultSetData 。
注:在 otherRec .[[Has]]
执行期间,O .[[SetData]]
的元素数量可能增加。
设置 thisSize 为 O .[[SetData]] 的当前元素数量。
否则,
令 keysIter 为 ? GetIteratorFromMethod (otherRec .[[SetObject]] , otherRec .[[Keys]] )。
令 next 为 not-started 。
重复,直到 next 不为 done ,
将 next 设为 ? IteratorStepValue (keysIter )。
如果 next 不为 done ,则
将 next 设为 CanonicalizeKeyedCollectionKey (next )。
令 inThis 为 SetDataHas (O .[[SetData]] , next )。
如果 inThis 为 true ,则
注:由于 other 是任意对象,其
"keys" 迭代器
可能会多次产出同一值。
如果 SetDataHas (resultSetData ,
next ) 为 false ,则
将 next 添加到
resultSetData 。
令 result 为 OrdinaryObjectCreate (%Set.prototype% ,
« [[SetData]] »)。
设置 result .[[SetData]] 为
resultSetData 。
返回 result 。
24.2.4.10 Set.prototype.isDisjointFrom ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] )。
令 otherRec 为 ? GetSetRecord (other )。
如果 SetDataSize (O .[[SetData]] ) ≤ otherRec .[[Size]] ,则
令 thisSize 为 O .[[SetData]]
的元素数量。
令 index 为 0。
重复,直到 index < thisSize ,
令 e 为 O .[[SetData]] [index ]。
设置 index 为 index + 1。
如果 e 不为 empty ,则
令 inOther 为 ToBoolean (?
Call (otherRec .[[Has]] , otherRec .[[SetObject]] , «
e »))。
如果 inOther 为 true ,返回
false 。
注:在 otherRec .[[Has]]
执行期间,O .[[SetData]]
的元素数量可能增加。
设置 thisSize 为 O .[[SetData]] 的当前元素数量。
否则,
令 keysIter 为 ? GetIteratorFromMethod (otherRec .[[SetObject]] , otherRec .[[Keys]] )。
令 next 为 not-started 。
重复,直到 next 不为 done ,
将 next 设为 ? IteratorStepValue (keysIter )。
如果 next 不为 done ,则
如果 SetDataHas (O .[[SetData]] , next ) 为
true ,则
执行 ? IteratorClose (keysIter ,
NormalCompletion (unused ))。
返回 false 。
返回 true 。
24.2.4.11 Set.prototype.isSubsetOf ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] )。
令 otherRec 为 ? GetSetRecord (other )。
如果 SetDataSize (O .[[SetData]] ) > otherRec .[[Size]] ,返回 false 。
令 thisSize 为 O .[[SetData]] 的元素数量。
令 index 为 0。
重复,直到 index < thisSize ,
令 e 为 O .[[SetData]] [index ]。
设置 index 为 index + 1。
如果 e 不为 empty ,则
令 inOther 为 ToBoolean (? Call (otherRec .[[Has]] , otherRec .[[SetObject]] , « e »))。
如果 inOther 为 false ,返回
false 。
注:在 otherRec .[[Has]]
执行期间,O .[[SetData]] 的元素数量可能增加。
设置 thisSize 为 O .[[SetData]] 的当前元素数量。
返回 true 。
24.2.4.12 Set.prototype.isSupersetOf ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] )。
令 otherRec 为 ? GetSetRecord (other )。
如果 SetDataSize (O .[[SetData]] ) < otherRec .[[Size]] ,返回 false 。
令 keysIter 为 ? GetIteratorFromMethod (otherRec .[[SetObject]] , otherRec .[[Keys]] )。
令 next 为 not-started 。
重复,直到 next 不为 done ,
将 next 设为 ? IteratorStepValue (keysIter )。
如果 next 不为 done ,则
如果 SetDataHas (O .[[SetData]] , next ) 为
false ,则
执行 ? IteratorClose (keysIter ,
NormalCompletion (unused ))。
返回 false 。
返回 true 。
24.2.4.13 Set.prototype.keys ( )
"keys" 属性的初始值为 %Set.prototype.values%,定义见 24.2.4.17 。
注
对于遍历目的,Set 类似于每个条目的键和值都相同的 Map。
24.2.4.14 get Set.prototype.size
Set.prototype.size 是一个 访问器属性 ,其 set 访问器函数为
undefined 。其 get 访问器函数被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[SetData]] )。
令 size 为 SetDataSize (S .[[SetData]] )。
返回 𝔽 (size )。
24.2.4.15 Set.prototype.symmetricDifference ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] )。
令 otherRec 为 ? GetSetRecord (other )。
令 keysIter 为 ? GetIteratorFromMethod (otherRec .[[SetObject]] , otherRec .[[Keys]] )。
令 resultSetData 为 O .[[SetData]]
的一个副本。
令 next 为 not-started 。
重复,直到 next 不为 done ,
将 next 设为 ? IteratorStepValue (keysIter )。
如果 next 不为 done ,则
将 next 设为 CanonicalizeKeyedCollectionKey (next )。
令 resultIndex 为 SetDataIndex (resultSetData ,
next )。
如果 resultIndex 为 not-found ,令
alreadyInResult 为 false 。否则令
alreadyInResult 为 true 。
如果 SetDataHas (O .[[SetData]] , next ) 为
true ,则
如果 alreadyInResult 为 true ,将
resultSetData [resultIndex ] 设为
empty 。
否则,
如果 alreadyInResult 为 false ,将
next 添加到 resultSetData 。
令 result 为 OrdinaryObjectCreate (%Set.prototype% ,
« [[SetData]] »)。
设置 result .[[SetData]] 为
resultSetData 。
返回 result 。
24.2.4.16 Set.prototype.union ( other )
该方法被调用时执行以下步骤:
令 O 为 this 值。
执行 ? RequireInternalSlot (O ,
[[SetData]] )。
令 otherRec 为 ? GetSetRecord (other )。
令 keysIter 为 ? GetIteratorFromMethod (otherRec .[[SetObject]] , otherRec .[[Keys]] )。
令 resultSetData 为 O .[[SetData]]
的一个副本。
令 next 为 not-started 。
重复,直到 next 不为 done ,
将 next 设为 ? IteratorStepValue (keysIter )。
如果 next 不为 done ,则
将 next 设为 CanonicalizeKeyedCollectionKey (next )。
如果 SetDataHas (resultSetData ,
next ) 为 false ,则
将 next 添加到 resultSetData 。
令 result 为 OrdinaryObjectCreate (%Set.prototype% ,
« [[SetData]] »)。
设置 result .[[SetData]] 为
resultSetData 。
返回 result 。
24.2.4.17 Set.prototype.values ( )
该方法被调用时执行以下步骤:
令 S 为 this 值。
返回 ? CreateSetIterator (S ,
value )。
24.2.4.18 Set.prototype [ %Symbol.iterator% ] ( )
%Symbol.iterator% 属性的初始值为
%Set.prototype.values%,定义见 24.2.4.17 。
24.2.4.19 Set.prototype [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"Set" 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
24.2.5 Set 实例的属性
Set 实例是 普通对象 ,它们继承自 Set 原型的属性。Set 实例还拥有 [[SetData]] 内部槽。
24.2.6 Set 迭代器对象
Set
迭代器 是一个 普通对象 ,结构如下定义,用于表示对某个特定 Set 实例对象的特定遍历。Set
迭代器对象没有具名的 构造函数 。相反,Set 迭代器对象是通过调用 Set 实例对象的某些方法创建的。
24.2.6.1 CreateSetIterator ( set , kind )
抽象操作 CreateSetIterator 接收参数 set (一个 ECMAScript 语言值 )和
kind (key+value 或 value ),返回
正常完成,包含 一个生成器,或
抛出完成 。用于为返回此类
迭代器 的 Set 方法创建 迭代器对象 。调用时执行以下步骤:
执行 ? RequireInternalSlot (set ,
[[SetData]] )。
令 closure 为一个新的 抽象闭包 ,无参数,捕获 set 和
kind ,调用时执行以下步骤:
令 index 为 0。
令 entries 为 set .[[SetData]] 。
令 numEntries 为 entries 的元素数量。
重复,直到 index < numEntries ,
令 e 为 entries [index ]。
设置 index 为 index + 1。
如果 e 不为 empty ,则
如果 kind 是 key+value ,则
令 result 为 CreateArrayFromList («
e , e »)。
执行 ? GeneratorYield (CreateIteratorResultObject (result ,
false ))。
否则,
断言 :kind
是 value 。
执行 ? GeneratorYield (CreateIteratorResultObject (e ,
false ))。
注:在 GeneratorYield
挂起本抽象操作执行期间,entries 的元素数量可能增加。
设置 numEntries 为 entries 的当前元素数量。
返回 undefined 。
返回 CreateIteratorFromClosure (closure ,
"%SetIteratorPrototype%" , %SetIteratorPrototype% )。
24.2.6.2 %SetIteratorPrototype% 对象
%SetIteratorPrototype% 对象:
24.2.6.2.1 %SetIteratorPrototype%.next ( )
返回 ? GeneratorResume (this
值, empty ,
"%SetIteratorPrototype%" )。
24.2.6.2.2 %SetIteratorPrototype% [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"Set Iterator" 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
true }.
24.3 WeakMap 对象
WeakMap 是键/值对的集合,其中键是对象和/或符号,值可以是任意的 ECMAScript 语言值 。WeakMap
可以用来查询是否包含某个特定键的键/值对,但没有机制用于枚举它所持有的所有键。在某些情况下,非 存活 的值会被从 WeakMap 的键中移除,详见 9.9.3 。
实现可能会对 WeakMap 的某个键/值对变得不可访问与被移除之间施加任意的延迟。如果这个延迟对 ECMAScript 程序是可观察的,则会带来不确定性,影响程序执行。因此,ECMAScript
的实现不得提供任何无需观察者持有该键即可观察 WeakMap 键的手段。
WeakMap 必须通过哈希表或其他机制实现,这些机制在平均情况下能提供次线性的键/值对访问时间。本规范中所用的数据结构仅用于描述 WeakMap 所需的可观察语义,而非实际的实现模型。
注
WeakMap 和 WeakSet 旨在为对象或符号动态关联状态,且如果没有 WeakMap 或 WeakSet
实例,该对象或符号变得不可访问并被垃圾回收机制回收时,不会“泄漏”内存资源。可以通过将 WeakMap 或 WeakSet 实例反向映射到每个对象/符号实现这一特性。或者,每个
WeakMap 或 WeakSet 实例可以内部存储其键和值数据,但这种方法需要 WeakMap/WeakSet 实现与垃圾回收器协作。下列参考文献介绍了对 WeakMap 和
WeakSet 实现可能有用的机制:
Barry Hayes. 1997. Ephemerons: a new finalization mechanism. 载于 Proceedings of the 12th
ACM SIGPLAN conference on Object-oriented programming, systems, languages, and
applications (OOPSLA '97) , A. Michael Berman (编辑). ACM, New York, NY, USA, 176-183,
http://doi.acm.org/10.1145/263698.263733 .
Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of
Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak
24.3.1 WeakMap 构造函数
WeakMap 构造函数 :
即 %WeakMap% 。
是 全局对象 的 "WeakMap" 属性的初始值。
作为 构造函数
调用时会创建并初始化一个新的 WeakMap。
不应作为普通函数调用,否则会抛出异常。
可以用作类定义的 extends 子句的值。想要继承指定 WeakMap 行为的子类 构造函数 必须包含对 WeakMap 构造函数 的
super 调用,以用必要的内部状态创建和初始化子类实例,以支持 WeakMap.prototype 内建方法。
24.3.1.1 WeakMap ( [ iterable ] )
该函数被调用时执行以下步骤:
如果 NewTarget 为 undefined ,抛出 TypeError 异常。
令 map 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%WeakMap.prototype%" , « [[WeakMapData]] »)。
设置 map .[[WeakMapData]] 为一个新的空 List 。
如果 iterable 为 undefined 或 null ,返回
map 。
令 adder 为 ? Get (map ,
"set" )。
如果 IsCallable (adder ) 为
false ,抛出 TypeError 异常。
返回 ? AddEntriesFromIterable (map ,
iterable , adder )。
注
如果参数 iterable 存在,期望它是一个实现了 %Symbol.iterator%
方法的对象,该方法返回一个 迭代器对象 ,会产生一个二元素 类数组对象 ,其第一个元素作为 WeakMap
的键,第二个元素为要与该键关联的值。
24.3.2 WeakMap 构造函数的属性
WeakMap 构造函数 :
24.3.2.1 WeakMap.prototype
WeakMap.prototype 的初始值为 WeakMap 原型对象 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
24.3.3 WeakMap 原型对象的属性
WeakMap 原型对象 :
24.3.3.1 WeakMap.prototype.constructor
WeakMap.prototype.constructor 的初始值为 %WeakMap% 。
24.3.3.2 WeakMap.prototype.delete ( key )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[WeakMapData]] )。
如果 CanBeHeldWeakly (key )
为 false ,返回 false 。
对于 M .[[WeakMapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为 true ,则
将 p .[[Key]] 设为
empty 。
将 p .[[Value]] 设为
empty 。
返回 true 。
返回 false 。
注
empty 作为规范设备用来表示一个条目已被删除。实际实现可能会采取其他操作,比如在内部数据结构中物理删除该条目。
24.3.3.3 WeakMap.prototype.get ( key )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[WeakMapData]] )。
如果 CanBeHeldWeakly (key )
为 false ,返回 undefined 。
对于 M .[[WeakMapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为
true ,返回 p .[[Value]] 。
返回 undefined 。
24.3.3.4 WeakMap.prototype.has ( key )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[WeakMapData]] )。
如果 CanBeHeldWeakly (key )
为 false ,返回 false 。
对于 M .[[WeakMapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为
true ,返回 true 。
返回 false 。
24.3.3.5 WeakMap.prototype.set ( key ,
value )
该方法被调用时执行以下步骤:
令 M 为 this 值。
执行 ? RequireInternalSlot (M ,
[[WeakMapData]] )。
如果 CanBeHeldWeakly (key )
为 false ,抛出 TypeError 异常。
对于 M .[[WeakMapData]] 中的每个 Record { [[Key]] , [[Value]] }
p ,执行
如果 p .[[Key]] 不为
empty 且 SameValue (p .[[Key]] , key ) 为 true ,则
将 p .[[Value]] 设为
value 。
返回 M 。
令 p 为 Record { [[Key]] : key , [[Value]] :
value }。
将 p 添加到 M .[[WeakMapData]] 。
返回 M 。
24.3.3.6 WeakMap.prototype [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"WeakMap" 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
24.3.4 WeakMap 实例的属性
WeakMap 实例是 普通对象 ,它们继承自 WeakMap 原型的属性。WeakMap 实例还拥有 [[WeakMapData]]
内部槽。
24.4 WeakSet 对象
WeakSet 是对象和/或符号的集合。在 WeakSet 的集合中,每个不同的对象或符号只能出现一次。WeakSet
可以用来查询是否包含某个特定值,但没有机制用于枚举它所持有的所有值。在某些情况下,非 存活 的值会被从 WeakSet 元素中移除,详见 9.9.3 。
实现可能会对 WeakSet 所包含的某个值变得不可访问与被移除之间施加任意的延迟。如果这个延迟对 ECMAScript 程序是可观察的,则会带来不确定性,影响程序执行。因此,ECMAScript
的实现不得提供任何无需观察者持有该值即可确定 WeakSet 是否包含该值的手段。
WeakSet 必须通过哈希表或其他机制实现,这些机制在平均情况下能提供次线性的元素访问时间。本规范中所用的数据结构仅用于描述 WeakSet 所需的可观察语义,而非实际的实现模型。
注
24.4.1 WeakSet 构造函数
WeakSet 构造函数 :
即 %WeakSet% 。
是 全局对象 的 "WeakSet" 属性的初始值。
作为 构造函数
调用时会创建并初始化一个新的 WeakSet。
不应作为普通函数调用,否则会抛出异常。
可以用作类定义的 extends 子句的值。想要继承指定 WeakSet 行为的子类 构造函数 必须包含对 WeakSet 构造函数 的
super 调用,以用必要的内部状态创建和初始化子类实例,以支持 WeakSet.prototype 内建方法。
24.4.1.1 WeakSet ( [ iterable ] )
该函数被调用时执行以下步骤:
如果 NewTarget 为 undefined ,抛出 TypeError 异常。
令 set 为 ? OrdinaryCreateFromConstructor (NewTarget,
"%WeakSet.prototype%" , « [[WeakSetData]] »)。
设置 set .[[WeakSetData]] 为一个新的空 List 。
如果 iterable 为 undefined 或 null ,返回
set 。
令 adder 为 ? Get (set ,
"add" )。
如果 IsCallable (adder ) 为
false ,抛出 TypeError 异常。
令 iteratorRecord 为 ? GetIterator (iterable ,
sync )。
重复,
令 next 为 ? IteratorStepValue (iteratorRecord )。
如果 next 为 done ,返回 set 。
令 status 为 Completion (Call (adder ,
set , « next »))。
IfAbruptCloseIterator (status ,
iteratorRecord )。
24.4.2 WeakSet 构造函数的属性
WeakSet 构造函数 :
24.4.2.1 WeakSet.prototype
WeakSet.prototype 的初始值为 WeakSet 原型对象 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }。
24.4.3 WeakSet 原型对象的属性
WeakSet 原型对象 :
24.4.3.1 WeakSet.prototype.add ( value )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[WeakSetData]] )。
如果 CanBeHeldWeakly (value )
为 false ,抛出 TypeError 异常。
对于 S .[[WeakSetData]] 的每个元素 e ,执行
如果 e 不为 empty 且 SameValue (e ,
value ) 为 true ,则
返回 S 。
将 value 添加到 S .[[WeakSetData]] 。
返回 S 。
24.4.3.2 WeakSet.prototype.constructor
WeakSet.prototype.constructor 的初始值为 %WeakSet% 。
24.4.3.3 WeakSet.prototype.delete ( value )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[WeakSetData]] )。
如果 CanBeHeldWeakly (value )
为 false ,返回 false 。
对于 S .[[WeakSetData]] 的每个元素 e ,执行
如果 e 不为 empty 且 SameValue (e ,
value ) 为 true ,则
将 S .[[WeakSetData]] 中值为
e 的元素替换为值为 empty 的元素。
返回 true 。
返回 false 。
注
empty 作为规范设备用来表示一个条目已被删除。实际实现可能会采取其他操作,比如在内部数据结构中物理删除该条目。
24.4.3.4 WeakSet.prototype.has ( value )
该方法被调用时执行以下步骤:
令 S 为 this 值。
执行 ? RequireInternalSlot (S ,
[[WeakSetData]] )。
如果 CanBeHeldWeakly (value )
为 false ,返回 false 。
对于 S .[[WeakSetData]] 的每个元素 e ,执行
如果 e 不为 empty 且 SameValue (e ,
value ) 为 true ,返回 true 。
返回 false 。
24.4.3.5 WeakSet.prototype [ %Symbol.toStringTag% ]
%Symbol.toStringTag% 属性的初始值为字符串值
"WeakSet" 。
该属性具有属性 { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }。
24.4.4 WeakSet 实例的属性
WeakSet 实例是 普通对象 ,它们继承自 WeakSet 原型的属性。WeakSet 实例还拥有 [[WeakSetData]]
内部槽。
24.5 键控集合的抽象操作
24.5.1 CanonicalizeKeyedCollectionKey ( key )
抽象操作 CanonicalizeKeyedCollectionKey 接收参数 key (一个 ECMAScript 语言值 ),并返回一个 ECMAScript 语言值 。调用时执行以下步骤:
如果 key 是 -0 𝔽 ,返回
+0 𝔽 。
返回 key 。
25 Structured Data
25.1 ArrayBuffer Objects
25.1.1 Notation
The descriptions below in this section, 25.4 , and 29 use the read-modify-write
modification function internal data structure.
A read-modify-write
modification function is a mathematical function that is represented as an abstract
closure that takes two Lists of
byte
values as arguments and returns a List of byte
values . These abstract closures satisfy all of the following properties:
They perform all their algorithm steps atomically.
Their individual algorithm steps are not observable.
Note
To aid verifying that a read-modify-write modification function's algorithm steps
constitute a pure, mathematical function, the following editorial conventions are
recommended:
25.1.2 Fixed-length and Resizable ArrayBuffer Objects
A fixed-length ArrayBuffer is an ArrayBuffer whose byte length cannot
change after creation.
A resizable ArrayBuffer is an ArrayBuffer whose byte length may change
after creation via calls to ArrayBuffer.prototype.resize (
newLength ) .
The kind of ArrayBuffer object that is created depends on the arguments passed to ArrayBuffer ( length [ , options ]
) .
25.1.3 Abstract Operations For ArrayBuffer Objects
25.1.3.1 AllocateArrayBuffer ( constructor ,
byteLength [ , maxByteLength ] )
The abstract operation AllocateArrayBuffer takes arguments constructor (a
constructor ) and byteLength (a
non-negative integer ) and optional argument
maxByteLength (a non-negative integer or empty ) and returns
either a normal completion
containing an ArrayBuffer or a throw completion . It
is used to create an ArrayBuffer. It performs the following steps when called:
Let slots be « [[ArrayBufferData]] , [[ArrayBufferByteLength]] , [[ArrayBufferDetachKey]] ».
If maxByteLength is present and maxByteLength is not
empty , let allocatingResizableBuffer be
true ; otherwise let allocatingResizableBuffer be
false .
If allocatingResizableBuffer is true , then
If byteLength > maxByteLength , throw a
RangeError exception.
Append [[ArrayBufferMaxByteLength]] to
slots .
Let obj be ? OrdinaryCreateFromConstructor (constructor ,
"%ArrayBuffer.prototype%" , slots ).
Let block be ? CreateByteDataBlock (byteLength ).
Set obj .[[ArrayBufferData]] to block .
Set obj .[[ArrayBufferByteLength]] to
byteLength .
If allocatingResizableBuffer is true , then
If it is not possible to create a Data Block
block consisting of maxByteLength bytes, throw a
RangeError exception.
NOTE: Resizable ArrayBuffers are designed to be implementable with in-place
growth. Implementations may throw if, for example, virtual memory cannot be
reserved up front.
Set obj .[[ArrayBufferMaxByteLength]] to
maxByteLength .
Return obj .
25.1.3.2 ArrayBufferByteLength ( arrayBuffer ,
order )
The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an
ArrayBuffer or SharedArrayBuffer) and order (seq-cst or
unordered ) and returns a non-negative integer . It performs the following
steps when called:
If IsSharedArrayBuffer (arrayBuffer )
is true and arrayBuffer has an [[ArrayBufferByteLengthData]] internal slot, then
Let bufferByteLengthBlock be arrayBuffer .[[ArrayBufferByteLengthData]] .
Let rawLength be GetRawBytesFromSharedBlock (bufferByteLengthBlock ,
0, biguint64 , true ,
order ).
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent 's
Agent
Record .
Return ℝ (RawBytesToNumeric (biguint64 ,
rawLength , isLittleEndian )).
Assert :
IsDetachedBuffer (arrayBuffer )
is false .
Return arrayBuffer .[[ArrayBufferByteLength]] .
25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer ,
newLength , preserveResizability )
The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an
ECMAScript language value ),
newLength (an ECMAScript language value ), and
preserveResizability (preserve-resizability or
fixed-length ) and returns either a normal completion
containing an ArrayBuffer or a throw completion . It
performs the following steps when called:
Perform ? RequireInternalSlot (arrayBuffer ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (arrayBuffer )
is true , throw a TypeError exception.
If newLength is undefined , then
Let newByteLength be arrayBuffer .[[ArrayBufferByteLength]] .
Else,
Let newByteLength be ? ToIndex (newLength ).
If IsDetachedBuffer (arrayBuffer )
is true , throw a TypeError exception.
If preserveResizability is preserve-resizability
and IsFixedLengthArrayBuffer (arrayBuffer )
is false , then
Let newMaxByteLength be arrayBuffer .[[ArrayBufferMaxByteLength]] .
Else,
Let newMaxByteLength be empty .
If arrayBuffer .[[ArrayBufferDetachKey]] is not
undefined , throw a TypeError exception.
Let newBuffer be ? AllocateArrayBuffer (%ArrayBuffer% ,
newByteLength , newMaxByteLength ).
Let copyLength be min (newByteLength ,
arrayBuffer .[[ArrayBufferByteLength]] ).
Let fromBlock be arrayBuffer .[[ArrayBufferData]] .
Let toBlock be newBuffer .[[ArrayBufferData]] .
Perform CopyDataBlockBytes (toBlock ,
0, fromBlock , 0, copyLength ).
NOTE: Neither creation of the new Data Block nor copying
from the old Data Block are observable.
Implementations may implement this method as a zero-copy move or a
realloc.
Perform ! DetachArrayBuffer (arrayBuffer ).
Return newBuffer .
25.1.3.4 IsDetachedBuffer ( arrayBuffer )
The abstract operation IsDetachedBuffer takes argument arrayBuffer (an ArrayBuffer
or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:
If arrayBuffer .[[ArrayBufferData]] is
null , return true .
Return false .
25.1.3.5 DetachArrayBuffer ( arrayBuffer [ ,
key ] )
The abstract operation DetachArrayBuffer takes argument arrayBuffer (an
ArrayBuffer) and optional argument key (anything) and returns either a normal completion
containing unused or a throw completion . It
performs the following steps when called:
Assert :
IsSharedArrayBuffer (arrayBuffer )
is false .
If key is not present, set key to
undefined .
If arrayBuffer .[[ArrayBufferDetachKey]] is not
key , throw a TypeError exception.
Set arrayBuffer .[[ArrayBufferData]] to
null .
Set arrayBuffer .[[ArrayBufferByteLength]] to 0.
Return unused .
Note
Detaching an ArrayBuffer instance disassociates the Data Block used as its
backing store from the instance and sets the byte length of the buffer to 0.
25.1.3.6 CloneArrayBuffer ( srcBuffer ,
srcByteOffset , srcLength )
The abstract operation CloneArrayBuffer takes arguments srcBuffer (an ArrayBuffer
or a SharedArrayBuffer), srcByteOffset (a non-negative integer ), and srcLength (a
non-negative integer ) and returns either a normal completion
containing an ArrayBuffer or a throw completion . It
creates a new ArrayBuffer whose data is a copy of srcBuffer 's data over the range
starting at srcByteOffset and continuing for srcLength bytes. It
performs the following steps when called:
Assert :
IsDetachedBuffer (srcBuffer )
is false .
Let targetBuffer be ? AllocateArrayBuffer (%ArrayBuffer% ,
srcLength ).
Let srcBlock be srcBuffer .[[ArrayBufferData]] .
Let targetBlock be targetBuffer .[[ArrayBufferData]] .
Perform CopyDataBlockBytes (targetBlock ,
0, srcBlock , srcByteOffset , srcLength ).
Return targetBuffer .
25.1.3.7 GetArrayBufferMaxByteLengthOption ( options
)
The abstract operation GetArrayBufferMaxByteLengthOption takes argument options
(an ECMAScript language value ) and
returns either a normal completion
containing either a non-negative integer or
empty , or a throw completion . It
performs the following steps when called:
If options is not an Object , return
empty .
Let maxByteLength be ? Get (options ,
"maxByteLength" ).
If maxByteLength is undefined , return
empty .
Return ? ToIndex (maxByteLength ).
25.1.3.8 HostResizeArrayBuffer ( buffer ,
newByteLength )
The host-defined abstract operation
HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer) and
newByteLength (a non-negative integer ) and returns either a normal completion
containing either handled or
unhandled , or a throw completion . It
gives the host an
opportunity to perform implementation-defined resizing of
buffer . If the host chooses not to handle resizing of
buffer , it may return unhandled for the default behaviour.
The implementation of HostResizeArrayBuffer must conform to the following requirements:
The abstract operation does not detach buffer .
If the abstract operation completes normally with handled ,
buffer .[[ArrayBufferByteLength]] is
newByteLength .
The default implementation of HostResizeArrayBuffer is to return NormalCompletion (unhandled ).
25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )
The abstract operation IsFixedLengthArrayBuffer takes argument arrayBuffer (an
ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps
when called:
If arrayBuffer has an [[ArrayBufferMaxByteLength]] internal slot, return
false .
Return true .
25.1.3.10 IsUnsignedElementType ( type )
The abstract operation IsUnsignedElementType takes argument type (a TypedArray element type ) and returns a
Boolean. It verifies if the argument type is an unsigned TypedArray element type . It performs
the following steps when called:
If type is one of uint8 ,
uint8clamped , uint16 ,
uint32 , or biguint64 , return
true .
Return false .
25.1.3.11 IsUnclampedIntegerElementType ( type )
The abstract operation IsUnclampedIntegerElementType takes argument type (a
TypedArray element type ) and returns a
Boolean. It verifies if the argument type is an Integer TypedArray element type not including
uint8clamped . It performs the following steps when called:
If type is one of int8 ,
uint8 , int16 ,
uint16 , int32 , or
uint32 , return true .
Return false .
25.1.3.12 IsBigIntElementType ( type )
The abstract operation IsBigIntElementType takes argument type (a TypedArray element type ) and returns a
Boolean. It verifies if the argument type is a BigInt
TypedArray element type . It performs
the following steps when called:
If type is either biguint64 or
bigint64 , return true .
Return false .
25.1.3.13 IsNoTearConfiguration ( type ,
order )
The abstract operation IsNoTearConfiguration takes arguments type (a TypedArray element type ) and
order (seq-cst , unordered , or
init ) and returns a Boolean. It performs the following steps when
called:
If IsUnclampedIntegerElementType (type )
is true , return true .
If IsBigIntElementType (type )
is true and order is neither
init nor unordered , return
true .
Return false .
25.1.3.14 RawBytesToNumeric ( type ,
rawBytes , isLittleEndian )
The abstract operation RawBytesToNumeric takes arguments type (a TypedArray element type ),
rawBytes (a List of
byte
values ), and isLittleEndian (a Boolean) and returns a
Number or a BigInt. It performs the following steps when called:
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
If isLittleEndian is false , reverse the order of the
elements of rawBytes .
If type is float16 , then
Let value be the byte elements of rawBytes
concatenated and interpreted as a little-endian bit string encoding of an
IEEE 754-2019 binary16
value.
If value is a NaN, return NaN .
Return the Number value that corresponds to value .
If type is float32 , then
Let value be the byte elements of rawBytes
concatenated and interpreted as a little-endian bit string encoding of an
IEEE 754-2019 binary32
value.
If value is a NaN, return NaN .
Return the Number value that corresponds to value .
If type is float64 , then
Let value be the byte elements of rawBytes
concatenated and interpreted as a little-endian bit string encoding of an
IEEE 754-2019 binary64
value.
If value is a NaN, return NaN .
Return the Number value that corresponds to value .
If IsUnsignedElementType (type )
is true , then
Let intValue be the byte elements of rawBytes
concatenated and interpreted as a bit string encoding of an unsigned
little-endian binary number.
Else,
Let intValue be the byte elements of rawBytes
concatenated and interpreted as a bit string encoding of a binary
little-endian two's complement number of bit length elementSize ×
8.
If IsBigIntElementType (type )
is true , return the BigInt value that corresponds to
intValue .
Otherwise, return the Number value that corresponds to intValue .
25.1.3.15 GetRawBytesFromSharedBlock ( block ,
byteIndex , type , isTypedArray , order )
The abstract operation GetRawBytesFromSharedBlock takes arguments block (a
Shared Data
Block ), byteIndex (a non-negative integer ),
type (a TypedArray element type ),
isTypedArray (a Boolean), and order (seq-cst or
unordered ) and returns a List of byte
values . It performs the following steps when called:
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
Let execution be the [[CandidateExecution]]
field of the surrounding agent 's Agent
Record .
Let eventsRecord be the Agent Events
Record of execution .[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier ().
If isTypedArray is true and IsNoTearConfiguration (type ,
order ) is true , let noTear be
true ; otherwise let noTear be
false .
Let rawValue be a List of length
elementSize whose elements are nondeterministically chosen byte
values .
NOTE: In implementations, rawValue is the result of a non-atomic or
atomic read instruction on the underlying hardware. The nondeterminism is a semantic
prescription of the memory model to describe observable
behaviour of hardware with weak consistency.
Let readEvent be ReadSharedMemory { [[Order]] : order , [[NoTear]] : noTear , [[Block]] : block , [[ByteIndex]] : byteIndex , [[ElementSize]] : elementSize }.
Append readEvent to eventsRecord .[[EventList]] .
Append Chosen Value Record { [[Event]] : readEvent , [[ChosenValue]] : rawValue } to
execution .[[ChosenValues]] .
Return rawValue .
25.1.3.16 GetValueFromBuffer ( arrayBuffer ,
byteIndex , type , isTypedArray , order [ ,
isLittleEndian ] )
The abstract operation GetValueFromBuffer takes arguments arrayBuffer (an
ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer ),
type (a TypedArray element type ),
isTypedArray (a Boolean), and order (seq-cst or
unordered ) and optional argument isLittleEndian (a
Boolean) and returns a Number or a BigInt. It performs the following steps when called:
Assert :
IsDetachedBuffer (arrayBuffer )
is false .
Assert :
There are sufficient bytes in arrayBuffer starting at
byteIndex to represent a value of type .
Let block be arrayBuffer .[[ArrayBufferData]] .
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
If IsSharedArrayBuffer (arrayBuffer )
is true , then
Assert : block is a
Shared Data Block .
Let rawValue be GetRawBytesFromSharedBlock (block ,
byteIndex , type , isTypedArray ,
order ).
Else,
Let rawValue be a List
whose elements are bytes from block at indices in the interval from byteIndex
(inclusive) to byteIndex + elementSize (exclusive).
Assert :
The number of elements in rawValue is elementSize .
If isLittleEndian is not present, set isLittleEndian to the
value of the [[LittleEndian]] field of the surrounding agent 's Agent
Record .
Return RawBytesToNumeric (type ,
rawValue , isLittleEndian ).
25.1.3.17 NumericToRawBytes ( type , value ,
isLittleEndian )
The abstract operation NumericToRawBytes takes arguments type (a TypedArray element type ),
value (a Number or a BigInt), and isLittleEndian (a Boolean) and
returns a List of byte
values . It performs the following steps when called:
If type is float16 , then
Let rawBytes be a List
whose elements are the 2 bytes that are the result of converting
value to IEEE 754-2019 binary16
format using roundTiesToEven mode. The bytes are arranged in little endian
order. If value is NaN , rawBytes
may be set to any implementation chosen IEEE 754-2019
binary16 format NaN encoding. An implementation must always choose the same
encoding for each implementation distinguishable NaN
value.
Else if type is float32 , then
Let rawBytes be a List
whose elements are the 4 bytes that are the result of converting
value to IEEE 754-2019 binary32
format using roundTiesToEven mode. The bytes are arranged in little endian
order. If value is NaN , rawBytes
may be set to any implementation chosen IEEE 754-2019
binary32 format NaN encoding. An implementation must always choose the same
encoding for each implementation distinguishable NaN
value.
Else if type is float64 , then
Let rawBytes be a List
whose elements are the 8 bytes that are the IEEE 754-2019 binary64
format encoding of value . The bytes are arranged in little endian
order. If value is NaN , rawBytes
may be set to any implementation chosen IEEE 754-2019
binary64 format NaN encoding. An implementation must always choose the same
encoding for each implementation distinguishable NaN
value.
Else,
Let n be the Element Size value specified in Table 75
for Element Type type .
Let conversionOperation be the abstract operation named in the
Conversion Operation column in Table 75
for Element Type type .
Let intValue be ℝ (conversionOperation (value )).
If intValue ≥ 0, then
Let rawBytes be a List
whose elements are the n -byte binary encoding of
intValue . The bytes are ordered in little endian order.
Else,
Let rawBytes be a List
whose elements are the n -byte binary two's complement
encoding of intValue . The bytes are ordered in little
endian order.
If isLittleEndian is false , reverse the order of the
elements of rawBytes .
Return rawBytes .
25.1.3.18 SetValueInBuffer ( arrayBuffer ,
byteIndex , type , value , isTypedArray ,
order [ , isLittleEndian ] )
The abstract operation SetValueInBuffer takes arguments arrayBuffer (an
ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer ),
type (a TypedArray element type ),
value (a Number or a BigInt), isTypedArray (a Boolean), and
order (seq-cst , unordered , or
init ) and optional argument isLittleEndian (a Boolean) and
returns unused . It performs the following steps when called:
Assert :
IsDetachedBuffer (arrayBuffer )
is false .
Assert :
There are sufficient bytes in arrayBuffer starting at
byteIndex to represent a value of type .
Assert :
value is a
BigInt if IsBigIntElementType (type )
is true ; otherwise, value is a
Number .
Let block be arrayBuffer .[[ArrayBufferData]] .
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
If isLittleEndian is not present, set isLittleEndian to the
value of the [[LittleEndian]] field of the surrounding agent 's Agent
Record .
Let rawBytes be NumericToRawBytes (type ,
value , isLittleEndian ).
If IsSharedArrayBuffer (arrayBuffer )
is true , then
Let execution be the [[CandidateExecution]] field of the surrounding agent 's
Agent
Record .
Let eventsRecord be the Agent Events
Record of execution .[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier ().
If isTypedArray is true and IsNoTearConfiguration (type ,
order ) is true , let noTear be
true ; otherwise let noTear be
false .
Append WriteSharedMemory
{ [[Order]] : order , [[NoTear]] : noTear , [[Block]] : block , [[ByteIndex]] : byteIndex , [[ElementSize]] : elementSize , [[Payload]] : rawBytes } to
eventsRecord .[[EventList]] .
Else,
Store the individual bytes of rawBytes into block ,
starting at block [byteIndex ].
Return unused .
25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer ,
byteIndex , type , value , op )
The abstract operation GetModifySetValueInBuffer takes arguments arrayBuffer (an
ArrayBuffer or a SharedArrayBuffer), byteIndex (a non-negative integer ),
type (a TypedArray element type ),
value (a Number or a BigInt), and op (a read-modify-write modification
function ) and returns a Number or a BigInt. It performs the following
steps when called:
Assert :
IsDetachedBuffer (arrayBuffer )
is false .
Assert :
There are sufficient bytes in arrayBuffer starting at
byteIndex to represent a value of type .
Assert :
value is a
BigInt if IsBigIntElementType (type )
is true ; otherwise, value is a
Number .
Let block be arrayBuffer .[[ArrayBufferData]] .
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent 's Agent
Record .
Let rawBytes be NumericToRawBytes (type ,
value , isLittleEndian ).
If IsSharedArrayBuffer (arrayBuffer )
is true , then
Let execution be the [[CandidateExecution]] field of the surrounding agent 's
Agent
Record .
Let eventsRecord be the Agent Events
Record of execution .[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier ().
Let rawBytesRead be a List
of length elementSize whose elements are nondeterministically
chosen byte values .
NOTE: In implementations, rawBytesRead is the result of a
load-link, of a load-exclusive, or of an operand of a read-modify-write
instruction on the underlying hardware. The nondeterminism is a semantic
prescription of the memory model to describe
observable behaviour of hardware with weak consistency.
Let rmwEvent be ReadModifyWriteSharedMemory
{ [[Order]] : seq-cst , [[NoTear]] : true , [[Block]] : block , [[ByteIndex]] : byteIndex , [[ElementSize]] : elementSize , [[Payload]] : rawBytes , [[ModifyOp]] : op }.
Append rmwEvent to eventsRecord .[[EventList]] .
Append Chosen Value Record
{ [[Event]] : rmwEvent , [[ChosenValue]] : rawBytesRead } to
execution .[[ChosenValues]] .
Else,
Let rawBytesRead be a List
of length elementSize whose elements are the sequence of
elementSize bytes starting with
block [byteIndex ].
Let rawBytesModified be op (rawBytesRead ,
rawBytes ).
Store the individual bytes of rawBytesModified into
block , starting at block [byteIndex ].
Return RawBytesToNumeric (type ,
rawBytesRead , isLittleEndian ).
25.1.4 The ArrayBuffer Constructor
The ArrayBuffer constructor :
is %ArrayBuffer% .
is the initial value of the "ArrayBuffer" property of the global
object .
creates and initializes a new ArrayBuffer when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
may be used as the value of an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
ArrayBuffer behaviour must include a super call to the ArrayBuffer constructor to
create and initialize subclass instances with the internal state necessary to support the
ArrayBuffer.prototype built-in methods.
25.1.4.1 ArrayBuffer ( length [ , options
] )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
Let byteLength be ? ToIndex (length ).
Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption (options ).
Return ? AllocateArrayBuffer (NewTarget,
byteLength , requestedMaxByteLength ).
25.1.5 Properties of the ArrayBuffer Constructor
The ArrayBuffer constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
25.1.5.1 ArrayBuffer.isView ( arg )
This function performs the following steps when called:
If arg is not an Object , return
false .
If arg has a [[ViewedArrayBuffer]] internal
slot, return true .
Return false .
25.1.5.2 ArrayBuffer.prototype
The initial value of ArrayBuffer.prototype is the ArrayBuffer prototype
object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
25.1.5.3 get ArrayBuffer [ %Symbol.species% ]
ArrayBuffer[%Symbol.species%] is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Return the this value.
The value of the "name" property of this function is "get
[Symbol.species]" .
Note
ArrayBuffer.prototype.slice (
start , end ) normally uses its
this value's constructor to create a derived object.
However, a subclass constructor may over-ride that default
behaviour for the ArrayBuffer.prototype.slice (
start , end ) method by redefining its
%Symbol.species% property.
25.1.6 Properties of the ArrayBuffer Prototype Object
The ArrayBuffer prototype object :
is %ArrayBuffer.prototype% .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
is an ordinary
object .
does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.
25.1.6.1 get ArrayBuffer.prototype.byteLength
ArrayBuffer.prototype.byteLength is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is true , throw a TypeError exception.
If IsDetachedBuffer (O )
is true , return +0 𝔽 .
Let length be O .[[ArrayBufferByteLength]] .
Return 𝔽 (length ).
25.1.6.2 ArrayBuffer.prototype.constructor
The initial value of ArrayBuffer.prototype.constructor is %ArrayBuffer% .
25.1.6.3 get ArrayBuffer.prototype.detached
ArrayBuffer.prototype.detached is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is true , throw a TypeError exception.
Return IsDetachedBuffer (O ).
25.1.6.4 get ArrayBuffer.prototype.maxByteLength
ArrayBuffer.prototype.maxByteLength is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is true , throw a TypeError exception.
If IsDetachedBuffer (O )
is true , return +0 𝔽 .
If IsFixedLengthArrayBuffer (O )
is true , then
Let length be O .[[ArrayBufferByteLength]] .
Else,
Let length be O .[[ArrayBufferMaxByteLength]] .
Return 𝔽 (length ).
25.1.6.5 get ArrayBuffer.prototype.resizable
ArrayBuffer.prototype.resizable is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is true , throw a TypeError exception.
If IsFixedLengthArrayBuffer (O )
is false , return true ; otherwise return
false .
25.1.6.6 ArrayBuffer.prototype.resize ( newLength )
This method performs the following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferMaxByteLength]] ).
If IsSharedArrayBuffer (O )
is true , throw a TypeError exception.
Let newByteLength be ? ToIndex (newLength ).
If IsDetachedBuffer (O )
is true , throw a TypeError exception.
If newByteLength > O .[[ArrayBufferMaxByteLength]] , throw a
RangeError exception.
Let hostHandled be ? HostResizeArrayBuffer (O ,
newByteLength ).
If hostHandled is handled , return
undefined .
Let oldBlock be O .[[ArrayBufferData]] .
Let newBlock be ? CreateByteDataBlock (newByteLength ).
Let copyLength be min (newByteLength ,
O .[[ArrayBufferByteLength]] ).
Perform CopyDataBlockBytes (newBlock ,
0, oldBlock , 0, copyLength ).
NOTE: Neither creation of the new Data Block nor copying
from the old Data Block are observable.
Implementations may implement this method as in-place growth or shrinkage.
Set O .[[ArrayBufferData]] to
newBlock .
Set O .[[ArrayBufferByteLength]] to
newByteLength .
Return undefined .
25.1.6.7 ArrayBuffer.prototype.slice ( start ,
end )
This method performs the following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is true , throw a TypeError exception.
If IsDetachedBuffer (O )
is true , throw a TypeError exception.
Let len be O .[[ArrayBufferByteLength]] .
Let relativeStart be ? ToIntegerOrInfinity (start ).
If relativeStart = -∞, let first be 0.
Else if relativeStart < 0, let first be max (len
+ relativeStart , 0).
Else, let first be min (relativeStart ,
len ).
If end is undefined , let relativeEnd be
len ; else let relativeEnd be ? ToIntegerOrInfinity (end ).
If relativeEnd = -∞, let final be 0.
Else if relativeEnd < 0, let final be max (len +
relativeEnd , 0).
Else, let final be min (relativeEnd , len ).
Let newLen be max (final - first , 0).
Let ctor be ? SpeciesConstructor (O ,
%ArrayBuffer% ).
Let new be ? Construct (ctor , « 𝔽 (newLen ) »).
Perform ? RequireInternalSlot (new ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (new )
is true , throw a TypeError exception.
If IsDetachedBuffer (new )
is true , throw a TypeError exception.
If SameValue (new , O )
is true , throw a TypeError exception.
If new .[[ArrayBufferByteLength]] <
newLen , throw a TypeError exception.
NOTE: Side-effects of the above steps may have detached or resized O .
If IsDetachedBuffer (O )
is true , throw a TypeError exception.
Let fromBuf be O .[[ArrayBufferData]] .
Let toBuf be new .[[ArrayBufferData]] .
Let currentLen be O .[[ArrayBufferByteLength]] .
If first < currentLen , then
Let count be min (newLen ,
currentLen - first ).
Perform CopyDataBlockBytes (toBuf ,
0, fromBuf , first , count ).
Return new .
25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength
] )
This method performs the following steps when called:
Let O be the this value.
Return ? ArrayBufferCopyAndDetach (O ,
newLength , preserve-resizability ).
25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [
newLength ] )
This method performs the following steps when called:
Let O be the this value.
Return ? ArrayBufferCopyAndDetach (O ,
newLength , fixed-length ).
25.1.6.10 ArrayBuffer.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "ArrayBuffer" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
25.1.7 Properties of ArrayBuffer Instances
ArrayBuffer instances inherit properties from the ArrayBuffer prototype
object . ArrayBuffer instances each have an [[ArrayBufferData]] internal slot, an [[ArrayBufferByteLength]] internal slot, and an [[ArrayBufferDetachKey]] internal slot. ArrayBuffer instances which are
resizable each have an [[ArrayBufferMaxByteLength]] internal slot.
ArrayBuffer instances whose [[ArrayBufferData]] is
null are considered to be detached and all operators to access or modify data
contained in the ArrayBuffer instance will fail.
ArrayBuffer instances whose [[ArrayBufferDetachKey]] is set to a value
other than undefined need to have all DetachArrayBuffer calls
passing that same "detach key" as an argument, otherwise a TypeError will result. This internal
slot is only ever set by certain embedding environments, not by algorithms in this
specification.
25.1.8 Resizable ArrayBuffer Guidelines
Note 1
The following are guidelines for ECMAScript programmers working with resizable
ArrayBuffer .
We recommend that programs be tested in their deployment environments where possible. The
amount of available physical memory differs greatly between hardware devices. Similarly,
virtual memory subsystems also differ greatly between hardware devices as well as
operating systems. An application that runs without out-of-memory errors on a 64-bit
desktop web browser could run out of memory on a 32-bit mobile web browser.
When choosing a value for the "maxByteLength" option for resizable
ArrayBuffer , we recommend that the smallest possible size for the
application be chosen. We recommend that "maxByteLength" does not
exceed 1,073,741,824 (230 bytes or 1GiB).
Please note that successfully constructing a resizable
ArrayBuffer for a particular maximum size does not guarantee that
future resizes will succeed.
Note 2
The following are guidelines for ECMAScript implementers implementing resizable
ArrayBuffer .
Resizable
ArrayBuffer can be implemented as copying upon resize, as
in-place growth via reserving virtual memory up front, or as a combination of both for
different values of the constructor 's
"maxByteLength" option.
If a host is
multi-tenanted (i.e. it runs many ECMAScript applications simultaneously), such as a web
browser, and its implementations choose to implement in-place growth by reserving
virtual memory, we recommend that both 32-bit and 64-bit implementations throw for
values of "maxByteLength" ≥ 1GiB to 1.5GiB. This is to reduce the
likelihood a single application can exhaust the virtual memory address space and to
reduce interoperability risk.
If a host does not
have virtual memory, such as those running on embedded devices without an MMU, or if a
host only
implements resizing by copying, it may accept any Number value
for the "maxByteLength" option. However, we
recommend a RangeError be thrown if a memory block of the requested
size can never be allocated. For example, if the requested size is greater than the
maximum amount of usable memory on the device.
25.2 SharedArrayBuffer Objects
25.2.1 Fixed-length and Growable SharedArrayBuffer Objects
A fixed-length SharedArrayBuffer is a SharedArrayBuffer whose byte
length cannot change after creation.
A growable SharedArrayBuffer is a SharedArrayBuffer whose byte length
may increase after creation via calls to SharedArrayBuffer.prototype.grow (
newLength ) .
The kind of SharedArrayBuffer object that is created depends on the arguments passed to SharedArrayBuffer ( length [ ,
options ] ) .
25.2.2 Abstract Operations for SharedArrayBuffer Objects
25.2.2.1 AllocateSharedArrayBuffer ( constructor ,
byteLength [ , maxByteLength ] )
The abstract operation AllocateSharedArrayBuffer takes arguments constructor (a
constructor ) and byteLength (a
non-negative integer ) and optional argument
maxByteLength (a non-negative integer or empty ) and returns
either a normal completion
containing a SharedArrayBuffer or a throw completion . It
is used to create a SharedArrayBuffer. It performs the following steps when called:
Let slots be « [[ArrayBufferData]] ».
If maxByteLength is present and maxByteLength is not
empty , let allocatingGrowableBuffer be
true ; otherwise let allocatingGrowableBuffer be
false .
If allocatingGrowableBuffer is true , then
If byteLength > maxByteLength , throw a
RangeError exception.
Append [[ArrayBufferByteLengthData]] and [[ArrayBufferMaxByteLength]] to slots .
Else,
Append [[ArrayBufferByteLength]] to
slots .
Let obj be ? OrdinaryCreateFromConstructor (constructor ,
"%SharedArrayBuffer.prototype%" , slots ).
If allocatingGrowableBuffer is true , let
allocLength be maxByteLength ; otherwise let
allocLength be byteLength .
Let block be ? CreateSharedByteDataBlock (allocLength ).
Set obj .[[ArrayBufferData]] to block .
If allocatingGrowableBuffer is true , then
Assert : byteLength ≤
maxByteLength .
Let byteLengthBlock be ? CreateSharedByteDataBlock (8).
Perform SetValueInBuffer (byteLengthBlock ,
0, biguint64 , ℤ (byteLength ),
true , seq-cst ).
Set obj .[[ArrayBufferByteLengthData]] to
byteLengthBlock .
Set obj .[[ArrayBufferMaxByteLength]] to
maxByteLength .
Else,
Set obj .[[ArrayBufferByteLength]] to
byteLength .
Return obj .
25.2.2.2 IsSharedArrayBuffer ( obj )
The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a
SharedArrayBuffer) and returns a Boolean. It tests whether an object is an ArrayBuffer, a
SharedArrayBuffer, or a subtype of either. It performs the following steps when called:
Let bufferData be obj .[[ArrayBufferData]] .
If bufferData is null , return
false .
If bufferData is a Data Block , return
false .
Assert :
bufferData is a Shared Data Block .
Return true .
25.2.2.3 HostGrowSharedArrayBuffer ( buffer ,
newByteLength )
The host-defined abstract operation
HostGrowSharedArrayBuffer takes arguments buffer (a SharedArrayBuffer) and
newByteLength (a non-negative integer ) and returns either a normal completion
containing either handled or
unhandled , or a throw completion . It
gives the host an
opportunity to perform implementation-defined growing of
buffer . If the host chooses not to handle growing of buffer ,
it may return unhandled for the default behaviour.
The implementation of HostGrowSharedArrayBuffer must conform to the following requirements:
If the abstract operation does not complete normally with
unhandled , and newByteLength < the current byte
length of the buffer or newByteLength > buffer .[[ArrayBufferMaxByteLength]] , throw a
RangeError exception.
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding
agent 's Agent Record . If the abstract operation
completes normally with handled , a WriteSharedMemory or
ReadModifyWriteSharedMemory
event whose [[Order]] is seq-cst , [[Payload]] is NumericToRawBytes (biguint64 ,
newByteLength , isLittleEndian ), [[Block]]
is buffer .[[ArrayBufferByteLengthData]] , [[ByteIndex]] is 0, and [[ElementSize]]
is 8 is added to the surrounding agent 's candidate execution such that
racing calls to SharedArrayBuffer.prototype.grow are not "lost", i.e.
silently do nothing.
Note
The second requirement above is intentionally vague about how or when the current
byte length of buffer is read. Because the byte length must be updated
via an atomic read-modify-write operation on the underlying hardware, architectures
that use load-link/store-conditional or load-exclusive/store-exclusive instruction
pairs may wish to keep the paired instructions close in the instruction stream. As
such, SharedArrayBuffer.prototype.grow itself does not perform bounds checking on
newByteLength before calling HostGrowSharedArrayBuffer, nor is there a
requirement on when the current byte length is read.
This is in contrast with HostResizeArrayBuffer ,
which is guaranteed that the value of newByteLength is ≥ 0 and ≤
buffer .[[ArrayBufferMaxByteLength]] .
The default implementation of HostGrowSharedArrayBuffer is to return NormalCompletion (unhandled ).
25.2.3 The SharedArrayBuffer Constructor
The SharedArrayBuffer constructor :
is %SharedArrayBuffer% .
is the initial value of the "SharedArrayBuffer" property of the global
object , if that property is present (see below).
creates and initializes a new SharedArrayBuffer when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
may be used as the value of an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
SharedArrayBuffer behaviour must include a super call to the SharedArrayBuffer
constructor to create and initialize subclass
instances with the internal state necessary to support the
SharedArrayBuffer.prototype built-in methods.
Whenever a host does not
provide concurrent access to SharedArrayBuffers it may omit the
"SharedArrayBuffer" property of the global object .
Note
Unlike an ArrayBuffer, a SharedArrayBuffer cannot become
detached, and its internal [[ArrayBufferData]] slot is never
null .
25.2.3.1 SharedArrayBuffer ( length [ ,
options ] )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
Let byteLength be ? ToIndex (length ).
Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption (options ).
Return ? AllocateSharedArrayBuffer (NewTarget,
byteLength , requestedMaxByteLength ).
25.2.4 Properties of the SharedArrayBuffer Constructor
The SharedArrayBuffer constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
25.2.4.1 SharedArrayBuffer.prototype
The initial value of SharedArrayBuffer.prototype is the SharedArrayBuffer
prototype object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
25.2.4.2 get SharedArrayBuffer [ %Symbol.species% ]
SharedArrayBuffer[%Symbol.species%] is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Return the this value.
The value of the "name" property of this function is "get
[Symbol.species]" .
25.2.5 Properties of the SharedArrayBuffer Prototype Object
The SharedArrayBuffer prototype object :
is %SharedArrayBuffer.prototype% .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
is an ordinary
object .
does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.
25.2.5.1 get SharedArrayBuffer.prototype.byteLength
SharedArrayBuffer.prototype.byteLength is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is false , throw a TypeError exception.
Let length be ArrayBufferByteLength (O ,
seq-cst ).
Return 𝔽 (length ).
25.2.5.2 SharedArrayBuffer.prototype.constructor
The initial value of SharedArrayBuffer.prototype.constructor is %SharedArrayBuffer% .
25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength
)
This method performs the following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferMaxByteLength]] ).
If IsSharedArrayBuffer (O )
is false , throw a TypeError exception.
Let newByteLength be ? ToIndex (newLength ).
Let hostHandled be ? HostGrowSharedArrayBuffer (O ,
newByteLength ).
If hostHandled is handled , return
undefined .
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent 's Agent
Record .
Let byteLengthBlock be O .[[ArrayBufferByteLengthData]] .
Let currentByteLengthRawBytes be GetRawBytesFromSharedBlock (byteLengthBlock ,
0, biguint64 , true ,
seq-cst ).
Let newByteLengthRawBytes be NumericToRawBytes (biguint64 ,
ℤ (newByteLength ),
isLittleEndian ).
Repeat,
NOTE: This is a compare-and-exchange loop to ensure that parallel, racing
grows of the same buffer are totally ordered, are not lost, and do not
silently do nothing. The loop exits if it was able to attempt to grow
uncontended.
Let currentByteLength be ℝ (RawBytesToNumeric (biguint64 ,
currentByteLengthRawBytes , isLittleEndian )).
If newByteLength = currentByteLength , return
undefined .
If newByteLength < currentByteLength or
newByteLength > O .[[ArrayBufferMaxByteLength]] , throw a
RangeError exception.
Let byteLengthDelta be newByteLength -
currentByteLength .
If it is impossible to create a new Shared Data
Block value consisting of byteLengthDelta
bytes, throw a RangeError exception.
NOTE: No new Shared Data Block is
constructed and used here. The observable behaviour of growable
SharedArrayBuffers is specified by allocating a max -sized Shared Data Block at
construction time, and this step captures the requirement that
implementations that run out of memory must throw a
RangeError .
Let readByteLengthRawBytes be AtomicCompareExchangeInSharedBlock (byteLengthBlock ,
0, 8, currentByteLengthRawBytes ,
newByteLengthRawBytes ).
If ByteListEqual (readByteLengthRawBytes ,
currentByteLengthRawBytes ) is true , return
undefined .
Set currentByteLengthRawBytes to
readByteLengthRawBytes .
Note
Spurious failures of the compare-exchange to update the length are prohibited. If the
bounds checking for the new length passes and the implementation is not out of
memory, a ReadModifyWriteSharedMemory
event (i.e. a successful compare-exchange) is always added into the candidate execution .
Parallel calls to SharedArrayBuffer.prototype.grow are totally ordered. For example,
consider two racing calls: sab.grow(10) and sab.grow(20).
One of the two calls is guaranteed to win the race. The call to
sab.grow(10) will never shrink sab even if
sab.grow(20) happened first; in that case it will instead throw a
RangeError.
25.2.5.4 get SharedArrayBuffer.prototype.growable
SharedArrayBuffer.prototype.growable is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is false , throw a TypeError exception.
If IsFixedLengthArrayBuffer (O )
is false , return true ; otherwise return
false .
25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength
SharedArrayBuffer.prototype.maxByteLength is an accessor
property whose set accessor function is undefined .
Its get accessor function performs the following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is false , throw a TypeError exception.
If IsFixedLengthArrayBuffer (O )
is true , then
Let length be O .[[ArrayBufferByteLength]] .
Else,
Let length be O .[[ArrayBufferMaxByteLength]] .
Return 𝔽 (length ).
25.2.5.6 SharedArrayBuffer.prototype.slice ( start ,
end )
This method performs the following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (O )
is false , throw a TypeError exception.
Let len be ArrayBufferByteLength (O ,
seq-cst ).
Let relativeStart be ? ToIntegerOrInfinity (start ).
If relativeStart = -∞, let first be 0.
Else if relativeStart < 0, let first be max (len
+ relativeStart , 0).
Else, let first be min (relativeStart ,
len ).
If end is undefined , let relativeEnd be
len ; else let relativeEnd be ? ToIntegerOrInfinity (end ).
If relativeEnd = -∞, let final be 0.
Else if relativeEnd < 0, let final be max (len +
relativeEnd , 0).
Else, let final be min (relativeEnd , len ).
Let newLen be max (final - first , 0).
Let ctor be ? SpeciesConstructor (O ,
%SharedArrayBuffer% ).
Let new be ? Construct (ctor , « 𝔽 (newLen ) »).
Perform ? RequireInternalSlot (new ,
[[ArrayBufferData]] ).
If IsSharedArrayBuffer (new )
is false , throw a TypeError exception.
If new .[[ArrayBufferData]] is O .[[ArrayBufferData]] , throw a TypeError
exception.
If ArrayBufferByteLength (new ,
seq-cst ) < newLen , throw a
TypeError exception.
Let fromBuf be O .[[ArrayBufferData]] .
Let toBuf be new .[[ArrayBufferData]] .
Perform CopyDataBlockBytes (toBuf ,
0, fromBuf , first , newLen ).
Return new .
25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "SharedArrayBuffer" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
25.2.6 Properties of SharedArrayBuffer Instances
SharedArrayBuffer instances inherit properties from the SharedArrayBuffer
prototype object . SharedArrayBuffer instances each have an [[ArrayBufferData]] internal slot. SharedArrayBuffer instances which are
not growable each have an [[ArrayBufferByteLength]] internal slot.
SharedArrayBuffer instances which are growable each have an [[ArrayBufferByteLengthData]] internal slot and an [[ArrayBufferMaxByteLength]] internal slot.
Note
SharedArrayBuffer instances, unlike ArrayBuffer instances, are never detached.
25.2.7 Growable SharedArrayBuffer Guidelines
Note 1
The following are guidelines for ECMAScript programmers working with growable
SharedArrayBuffer .
We recommend that programs be tested in their deployment environments where possible. The
amount of available physical memory differ greatly between hardware devices. Similarly,
virtual memory subsystems also differ greatly between hardware devices as well as
operating systems. An application that runs without out-of-memory errors on a 64-bit
desktop web browser could run out of memory on a 32-bit mobile web browser.
When choosing a value for the "maxByteLength" option for growable
SharedArrayBuffer , we recommend that the smallest possible size
for the application be chosen. We recommend that "maxByteLength" does
not exceed 1073741824, or 1GiB.
Please note that successfully constructing a growable
SharedArrayBuffer for a particular maximum size does not
guarantee that future grows will succeed.
Not all loads of a growable
SharedArrayBuffer 's length are synchronizing
seq-cst loads. Loads of the length that are for bounds-checking
of an integer-indexed property access, e.g.
u8[idx], are not synchronizing. In general, in the absence of explicit
synchronization, one property access being in-bound does not imply a subsequent property
access in the same agent is also in-bound. In contrast, explicit loads
of the length via the length and byteLength getters on
SharedArrayBuffer, %TypedArray% .prototype,
and DataView.prototype are synchronizing. Loads of the length that are performed by
built-in methods to check if a TypedArray is entirely out-of-bounds are also
synchronizing.
Note 2
The following are guidelines for ECMAScript implementers implementing growable
SharedArrayBuffer .
We recommend growable
SharedArrayBuffer be implemented as in-place growth via reserving
virtual memory up front.
Because grow operations can happen in parallel with memory accesses on a growable
SharedArrayBuffer , the constraints of the memory
model require that even unordered accesses do not "tear" (bits of
their values will not be mixed). In practice, this means the underlying data block of a
growable
SharedArrayBuffer cannot be grown by being copied without
stopping the world. We do not recommend stopping the world as an implementation strategy
because it introduces a serialization point and is slow.
Grown memory must appear zeroed from the moment of its creation, including to any racy
accesses in parallel. This can be accomplished via zero-filled-on-demand virtual memory
pages, or careful synchronization if manually zeroing memory.
Integer-indexed property access on
TypedArray views of growable
SharedArrayBuffers is intended to be optimizable similarly to access on TypedArray
views of non-growable SharedArrayBuffers, because integer-indexed property
loads on are not synchronizing on the underlying buffer's length (see programmer
guidelines above). For example, bounds checks for property accesses may still be hoisted
out of loops.
In practice it is difficult to implement growable
SharedArrayBuffer by copying on hosts that do not have virtual
memory, such as those running on embedded devices without an MMU. Memory usage behaviour
of growable SharedArrayBuffers on such hosts may significantly differ from that of
hosts with virtual
memory. Such hosts
should clearly communicate memory usage expectations to users.
25.3 DataView Objects
25.3.1 Abstract Operations For DataView Objects
25.3.1.1 DataView With Buffer Witness Records
A DataView With Buffer
Witness Record is a Record
value used to encapsulate a DataView along with a cached byte length of the viewed buffer.
It is used to help ensure there is a single shared memory read event of the byte length data
block when the viewed buffer is a growable SharedArrayBuffers.
DataView With Buffer Witness Records have the fields listed in Table 77 .
Table 77: DataView
With Buffer Witness Record Fields
Field Name
Value
Meaning
[[Object]]
a DataView
The DataView object whose buffer's byte length is loaded.
[[CachedBufferByteLength]]
a non-negative integer or
detached
The byte length of the object's [[ViewedArrayBuffer]] when the Record
was created.
25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj ,
order )
The abstract operation MakeDataViewWithBufferWitnessRecord takes arguments obj (a
DataView) and order (seq-cst or
unordered ) and returns a DataView With Buffer Witness
Record . It performs the following steps when called:
Let buffer be obj .[[ViewedArrayBuffer]] .
If IsDetachedBuffer (buffer )
is true , then
Let byteLength be detached .
Else,
Let byteLength be ArrayBufferByteLength (buffer ,
order ).
Return the DataView
With Buffer Witness Record { [[Object]] : obj , [[CachedBufferByteLength]] : byteLength }.
25.3.1.3 GetViewByteLength ( viewRecord )
The abstract operation GetViewByteLength takes argument viewRecord (a DataView With Buffer Witness
Record ) and returns a non-negative integer . It performs the following
steps when called:
Assert :
IsViewOutOfBounds (viewRecord )
is false .
Let view be viewRecord .[[Object]] .
If view .[[ByteLength]] is not
auto , return view .[[ByteLength]] .
Assert :
IsFixedLengthArrayBuffer (view .[[ViewedArrayBuffer]] ) is false .
Let byteOffset be view .[[ByteOffset]] .
Let byteLength be viewRecord .[[CachedBufferByteLength]] .
Assert :
byteLength is not detached .
Return byteLength - byteOffset .
25.3.1.4 IsViewOutOfBounds ( viewRecord )
The abstract operation IsViewOutOfBounds takes argument viewRecord (a DataView With Buffer Witness
Record ) and returns a Boolean. It performs the following steps when
called:
Let view be viewRecord .[[Object]] .
Let bufferByteLength be viewRecord .[[CachedBufferByteLength]] .
Assert :
IsDetachedBuffer (view .[[ViewedArrayBuffer]] ) is true if and
only if bufferByteLength is detached .
If bufferByteLength is detached , return
true .
Let byteOffsetStart be view .[[ByteOffset]] .
If view .[[ByteLength]] is
auto , then
Let byteOffsetEnd be bufferByteLength .
Else,
Let byteOffsetEnd be byteOffsetStart +
view .[[ByteLength]] .
If byteOffsetStart > bufferByteLength or
byteOffsetEnd > bufferByteLength , return
true .
NOTE: 0-length DataViews are not considered out-of-bounds.
Return false .
25.3.1.5 GetViewValue ( view ,
requestIndex , isLittleEndian , type )
The abstract operation GetViewValue takes arguments view (an ECMAScript language value ),
requestIndex (an ECMAScript language
value ), isLittleEndian (an ECMAScript language value ), and
type (a TypedArray element type ) and returns
either a normal completion
containing either a Number or a BigInt, or a throw completion . It
is used by functions on DataView instances to retrieve values from the view's buffer. It
performs the following steps when called:
Perform ? RequireInternalSlot (view ,
[[DataView]] ).
Assert :
view has a [[ViewedArrayBuffer]] internal slot.
Let getIndex be ? ToIndex (requestIndex ).
Set isLittleEndian to ToBoolean (isLittleEndian ).
Let viewOffset be view .[[ByteOffset]] .
Let viewRecord be MakeDataViewWithBufferWitnessRecord (view ,
unordered ).
NOTE: Bounds checking is not a synchronizing operation when view 's
backing buffer is a growable
SharedArrayBuffer .
If IsViewOutOfBounds (viewRecord )
is true , throw a TypeError exception.
Let viewSize be GetViewByteLength (viewRecord ).
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
If getIndex + elementSize > viewSize , throw a
RangeError exception.
Let bufferIndex be getIndex + viewOffset .
Return GetValueFromBuffer (view .[[ViewedArrayBuffer]] , bufferIndex ,
type , false , unordered ,
isLittleEndian ).
25.3.1.6 SetViewValue ( view ,
requestIndex , isLittleEndian , type , value )
The abstract operation SetViewValue takes arguments view (an ECMAScript language value ),
requestIndex (an ECMAScript language
value ), isLittleEndian (an ECMAScript language value ),
type (a TypedArray element type ), and
value (an ECMAScript language value ) and
returns either a normal completion
containing undefined or a throw completion . It
is used by functions on DataView instances to store values into the view's buffer. It
performs the following steps when called:
Perform ? RequireInternalSlot (view ,
[[DataView]] ).
Assert :
view has a [[ViewedArrayBuffer]] internal slot.
Let getIndex be ? ToIndex (requestIndex ).
If IsBigIntElementType (type )
is true , let numberValue be ? ToBigInt (value ).
Otherwise, let numberValue be ? ToNumber (value ).
Set isLittleEndian to ToBoolean (isLittleEndian ).
Let viewOffset be view .[[ByteOffset]] .
Let viewRecord be MakeDataViewWithBufferWitnessRecord (view ,
unordered ).
NOTE: Bounds checking is not a synchronizing operation when view 's
backing buffer is a growable
SharedArrayBuffer .
If IsViewOutOfBounds (viewRecord )
is true , throw a TypeError exception.
Let viewSize be GetViewByteLength (viewRecord ).
Let elementSize be the Element Size value specified in Table 75 for
Element Type type .
If getIndex + elementSize > viewSize , throw a
RangeError exception.
Let bufferIndex be getIndex + viewOffset .
Perform SetValueInBuffer (view .[[ViewedArrayBuffer]] , bufferIndex ,
type , numberValue , false ,
unordered , isLittleEndian ).
Return undefined .
25.3.2 The DataView Constructor
The DataView constructor :
is %DataView% .
is the initial value of the "DataView" property of the global
object .
creates and initializes a new DataView when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
may be used as the value of an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
DataView behaviour must include a super call to the DataView constructor to
create and initialize subclass instances with the internal state necessary to support the
DataView.prototype built-in methods.
25.3.2.1 DataView ( buffer [ , byteOffset
[ , byteLength ] ] )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
Perform ? RequireInternalSlot (buffer ,
[[ArrayBufferData]] ).
Let offset be ? ToIndex (byteOffset ).
If IsDetachedBuffer (buffer )
is true , throw a TypeError exception.
Let bufferByteLength be ArrayBufferByteLength (buffer ,
seq-cst ).
If offset > bufferByteLength , throw a
RangeError exception.
Let bufferIsFixedLength be IsFixedLengthArrayBuffer (buffer ).
If byteLength is undefined , then
If bufferIsFixedLength is true , then
Let viewByteLength be bufferByteLength -
offset .
Else,
Let viewByteLength be auto .
Else,
Let viewByteLength be ? ToIndex (byteLength ).
If offset + viewByteLength >
bufferByteLength , throw a RangeError
exception.
Let O be ? OrdinaryCreateFromConstructor (NewTarget,
"%DataView.prototype%" , « [[DataView]] ,
[[ViewedArrayBuffer]] , [[ByteLength]] , [[ByteOffset]] »).
If IsDetachedBuffer (buffer )
is true , throw a TypeError exception.
Set bufferByteLength to ArrayBufferByteLength (buffer ,
seq-cst ).
If offset > bufferByteLength , throw a
RangeError exception.
If byteLength is not undefined , then
If offset + viewByteLength >
bufferByteLength , throw a RangeError
exception.
Set O .[[ViewedArrayBuffer]] to
buffer .
Set O .[[ByteLength]] to
viewByteLength .
Set O .[[ByteOffset]] to offset .
Return O .
25.3.3 Properties of the DataView Constructor
The DataView constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
25.3.3.1 DataView.prototype
The initial value of DataView.prototype is the DataView prototype
object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
25.3.4 Properties of the DataView Prototype Object
The DataView prototype object :
is %DataView.prototype% .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
is an ordinary
object .
does not have a [[DataView]] , [[ViewedArrayBuffer]] , [[ByteLength]] , or
[[ByteOffset]] internal slot.
25.3.4.1 get DataView.prototype.buffer
DataView.prototype.buffer is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[DataView]] ).
Assert :
O has a [[ViewedArrayBuffer]] internal slot.
Let buffer be O .[[ViewedArrayBuffer]] .
Return buffer .
25.3.4.2 get DataView.prototype.byteLength
DataView.prototype.byteLength is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[DataView]] ).
Assert :
O has a [[ViewedArrayBuffer]] internal slot.
Let viewRecord be MakeDataViewWithBufferWitnessRecord (O ,
seq-cst ).
If IsViewOutOfBounds (viewRecord )
is true , throw a TypeError exception.
Let size be GetViewByteLength (viewRecord ).
Return 𝔽 (size ).
25.3.4.3 get DataView.prototype.byteOffset
DataView.prototype.byteOffset is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[DataView]] ).
Assert :
O has a [[ViewedArrayBuffer]] internal slot.
Let viewRecord be MakeDataViewWithBufferWitnessRecord (O ,
seq-cst ).
If IsViewOutOfBounds (viewRecord )
is true , throw a TypeError exception.
Let offset be O .[[ByteOffset]] .
Return 𝔽 (offset ).
25.3.4.4 DataView.prototype.constructor
The initial value of DataView.prototype.constructor is %DataView% .
25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset
[ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
Return ? GetViewValue (view ,
byteOffset , littleEndian , bigint64 ).
25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset
[ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
Return ? GetViewValue (view ,
byteOffset , littleEndian , biguint64 ).
25.3.4.7 DataView.prototype.getFloat16 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , float16 ).
25.3.4.8 DataView.prototype.getFloat32 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , float32 ).
25.3.4.9 DataView.prototype.getFloat64 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , float64 ).
25.3.4.10 DataView.prototype.getInt8 ( byteOffset )
This method performs the following steps when called:
Let view be the this value.
Return ? GetViewValue (view ,
byteOffset , true , int8 ).
25.3.4.11 DataView.prototype.getInt16 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , int16 ).
25.3.4.12 DataView.prototype.getInt32 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , int32 ).
25.3.4.13 DataView.prototype.getUint8 ( byteOffset )
This method performs the following steps when called:
Let view be the this value.
Return ? GetViewValue (view ,
byteOffset , true , uint8 ).
25.3.4.14 DataView.prototype.getUint16 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , uint16 ).
25.3.4.15 DataView.prototype.getUint32 ( byteOffset [
, littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? GetViewValue (view ,
byteOffset , littleEndian , uint32 ).
25.3.4.16 DataView.prototype.setBigInt64 (
byteOffset , value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
Return ? SetViewValue (view ,
byteOffset , littleEndian , bigint64 ,
value ).
25.3.4.17 DataView.prototype.setBigUint64 (
byteOffset , value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
Return ? SetViewValue (view ,
byteOffset , littleEndian , biguint64 ,
value ).
25.3.4.18 DataView.prototype.setFloat16 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , float16 ,
value ).
25.3.4.19 DataView.prototype.setFloat32 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , float32 ,
value ).
25.3.4.20 DataView.prototype.setFloat64 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , float64 ,
value ).
25.3.4.21 DataView.prototype.setInt8 ( byteOffset ,
value )
This method performs the following steps when called:
Let view be the this value.
Return ? SetViewValue (view ,
byteOffset , true , int8 ,
value ).
25.3.4.22 DataView.prototype.setInt16 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , int16 ,
value ).
25.3.4.23 DataView.prototype.setInt32 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , int32 ,
value ).
25.3.4.24 DataView.prototype.setUint8 ( byteOffset ,
value )
This method performs the following steps when called:
Let view be the this value.
Return ? SetViewValue (view ,
byteOffset , true , uint8 ,
value ).
25.3.4.25 DataView.prototype.setUint16 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , uint16 ,
value ).
25.3.4.26 DataView.prototype.setUint32 ( byteOffset ,
value [ , littleEndian ] )
This method performs the following steps when called:
Let view be the this value.
If littleEndian is not present, set littleEndian to
false .
Return ? SetViewValue (view ,
byteOffset , littleEndian , uint32 ,
value ).
25.3.4.27 DataView.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "DataView" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
25.3.5 Properties of DataView Instances
DataView instances are ordinary objects that inherit properties from the
DataView prototype
object . DataView instances each have [[DataView]] , [[ViewedArrayBuffer]] , [[ByteLength]] , and [[ByteOffset]] internal
slots.
Note
The value of the [[DataView]] internal slot is not used within
this specification. The simple presence of that internal slot is used within the
specification to identify objects created using the DataView constructor .
25.4 The Atomics Object
The Atomics object:
is %Atomics% .
is the initial value of the "Atomics" property of the global
object .
is an ordinary
object .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
does not have a [[Construct]] internal method; it cannot be used as a
constructor
with the new operator.
does not have a [[Call]] internal method; it cannot be invoked as a
function.
The Atomics object provides functions that operate indivisibly (atomically) on shared memory array
cells as well as functions that let agents wait for and dispatch primitive events. When used with
discipline, the Atomics functions allow multi-agent programs that communicate through shared memory to
execute in a well-understood order even on parallel CPUs. The rules that govern shared-memory
communication are provided by the memory model , defined below.
Note
For informative guidelines for programming and implementing shared memory in ECMAScript,
please see the notes at the end of the memory model section.
25.4.1 Waiter Record
A Waiter Record is a Record value used to
denote a particular call to Atomics.wait or Atomics.waitAsync.
A Waiter Record has fields listed in Table 78 .
Table 78: Waiter Record Fields
Field Name
Value
Meaning
[[AgentSignifier]]
an agent
signifier
The agent that called
Atomics.wait or Atomics.waitAsync.
[[PromiseCapability]]
a PromiseCapability
Record or blocking
If denoting a call to Atomics.waitAsync, the resulting promise,
otherwise blocking .
[[TimeoutTime]]
a non-negative extended
mathematical value
The earliest time by which timeout may be triggered; computed using
time values .
[[Result]]
"ok" or "timed-out"
The return value of the call.
25.4.2 WaiterList Records
A WaiterList Record is used to explain
waiting and notification of agents via Atomics.wait,
Atomics.waitAsync, and Atomics.notify.
A WaiterList Record has fields listed in Table 79 .
Table 79: WaiterList Record Fields
Field Name
Value
Meaning
[[Waiters]]
a List
of Waiter Records
The calls to Atomics.wait or Atomics.waitAsync
that are waiting on the location with which this WaiterList is associated.
[[MostRecentLeaveEvent]]
a Synchronize
event or empty
The event of the most recent leaving of its critical section , or
empty if its critical
section has never been entered.
There can be multiple Waiter Records in a WaiterList with the same
agent
signifier .
The agent
cluster has a store of WaiterList Records; the store is indexed by
(block , i ), where block is a Shared Data Block and i
a byte offset into the memory of block . WaiterList Records are agent -independent: a lookup in
the store of WaiterList Records by (block , i ) will result in the same
WaiterList Record in any agent in the agent cluster .
Each WaiterList Record has a critical
section that controls exclusive access to that WaiterList Record during evaluation.
Only a single agent may
enter a WaiterList Record's critical section at one time. Entering and leaving a WaiterList
Record's critical section is controlled by the abstract operations
EnterCriticalSection and LeaveCriticalSection . Operations on a
WaiterList Record—adding and removing waiting agents , traversing the list of agents , suspending and notifying agents on the list, setting
and retrieving the Synchronize event —may only be
performed by agents that
have entered the WaiterList Record's critical section.
25.4.3 Abstract Operations for Atomics
25.4.3.1 ValidateIntegerTypedArray ( typedArray ,
waitable )
The abstract operation ValidateIntegerTypedArray takes arguments typedArray (an
ECMAScript language value ) and
waitable (a Boolean) and returns either a normal completion
containing a TypedArray With Buffer Witness
Record , or a throw completion . It
performs the following steps when called:
Let taRecord be ? ValidateTypedArray (typedArray ,
unordered ).
NOTE: Bounds checking is not a synchronizing operation when typedArray 's
backing buffer is a growable
SharedArrayBuffer .
If waitable is true , then
If typedArray .[[TypedArrayName]] is
neither "Int32Array" nor
"BigInt64Array" , throw a TypeError
exception.
Else,
Let type be TypedArrayElementType (typedArray ).
If IsUnclampedIntegerElementType (type )
is false and IsBigIntElementType (type )
is false , throw a TypeError exception.
Return taRecord .
25.4.3.2 ValidateAtomicAccess ( taRecord ,
requestIndex )
The abstract operation ValidateAtomicAccess takes arguments taRecord (a TypedArray With Buffer Witness
Record ) and requestIndex (an ECMAScript language value ) and
returns either a normal completion
containing an integer or a throw completion . It
performs the following steps when called:
Let length be TypedArrayLength (taRecord ).
Let accessIndex be ? ToIndex (requestIndex ).
Assert :
accessIndex ≥ 0.
If accessIndex ≥ length , throw a RangeError
exception.
Let typedArray be taRecord .[[Object]] .
Let elementSize be TypedArrayElementSize (typedArray ).
Let offset be typedArray .[[ByteOffset]] .
Return (accessIndex × elementSize ) + offset .
25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray (
typedArray , requestIndex )
The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments
typedArray (an ECMAScript language value ) and
requestIndex (an ECMAScript language
value ) and returns either a normal completion
containing an integer or a throw completion . It
performs the following steps when called:
Let taRecord be ? ValidateIntegerTypedArray (typedArray ,
false ).
Return ? ValidateAtomicAccess (taRecord ,
requestIndex ).
25.4.3.4 RevalidateAtomicAccess ( typedArray ,
byteIndexInBuffer )
The abstract operation RevalidateAtomicAccess takes arguments typedArray (a
TypedArray ) and byteIndexInBuffer (an
integer ) and
returns either a normal completion
containing unused or a throw completion .
This operation revalidates the index within the backing buffer for atomic operations after
all argument coercions are performed in Atomics methods, as argument coercions can have
arbitrary side effects, which could cause the buffer to become out of bounds. This operation
does not throw when typedArray 's backing buffer is a SharedArrayBuffer. It
performs the following steps when called:
Let taRecord be MakeTypedArrayWithBufferWitnessRecord (typedArray ,
unordered ).
NOTE: Bounds checking is not a synchronizing operation when typedArray 's
backing buffer is a growable
SharedArrayBuffer .
If IsTypedArrayOutOfBounds (taRecord )
is true , throw a TypeError exception.
Assert :
byteIndexInBuffer ≥ typedArray .[[ByteOffset]] .
If byteIndexInBuffer ≥ taRecord .[[CachedBufferByteLength]] , throw a
RangeError exception.
Return unused .
25.4.3.5 GetWaiterList ( block , i )
The abstract operation GetWaiterList takes arguments block (a Shared Data
Block ) and i (a non-negative integer that is evenly divisible by 4)
and returns a WaiterList Record . It performs the
following steps when called:
Assert :
i and i + 3 are valid byte offsets within the memory of
block .
Return the WaiterList Record that is
referenced by the pair (block , i ).
25.4.3.6 EnterCriticalSection ( WL )
The abstract operation EnterCriticalSection takes argument WL (a WaiterList Record ) and returns
unused . It performs the following steps when called:
Assert :
The surrounding agent is not in the
critical section for any
WaiterList Record .
Wait until no agent is in the critical section for
WL , then enter the critical
section for WL (without allowing any other
agent to
enter).
If WL .[[MostRecentLeaveEvent]] is not
empty , then
NOTE: A WL whose critical
section has been entered at least once has a
Synchronize
event set by LeaveCriticalSection .
Let execution be the [[CandidateExecution]] field of the surrounding agent 's
Agent
Record .
Let eventsRecord be the Agent Events
Record of execution .[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier ().
Let enterEvent be a new Synchronize
event .
Append enterEvent to eventsRecord .[[EventList]] .
Append (WL .[[MostRecentLeaveEvent]] ,
enterEvent ) to eventsRecord .[[AgentSynchronizesWith]] .
Return unused .
EnterCriticalSection has contention when an agent attempting to enter the critical section must wait for another
agent to leave it.
When there is no contention, FIFO order of EnterCriticalSection calls is observable. When
there is contention, an implementation may choose an arbitrary order but may not cause an
agent to wait
indefinitely.
25.4.3.7 LeaveCriticalSection ( WL )
The abstract operation LeaveCriticalSection takes argument WL (a WaiterList Record ) and returns
unused . It performs the following steps when called:
Assert :
The surrounding agent is in the
critical section for
WL .
Let execution be the [[CandidateExecution]]
field of the surrounding agent 's Agent
Record .
Let eventsRecord be the Agent Events
Record of execution .[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier ().
Let leaveEvent be a new Synchronize
event .
Append leaveEvent to eventsRecord .[[EventList]] .
Set WL .[[MostRecentLeaveEvent]] to
leaveEvent .
Leave the critical section for
WL .
Return unused .
25.4.3.8 AddWaiter ( WL , waiterRecord )
The abstract operation AddWaiter takes arguments WL (a WaiterList Record ) and
waiterRecord (a Waiter Record ) and returns
unused . It performs the following steps when called:
Assert :
The surrounding agent is in the
critical section for
WL .
Assert :
There is no Waiter Record in WL .[[Waiters]] whose [[PromiseCapability]] field is waiterRecord .[[PromiseCapability]] and whose [[AgentSignifier]] field is waiterRecord .[[AgentSignifier]] .
Append waiterRecord to WL .[[Waiters]] .
Return unused .
25.4.3.9 RemoveWaiter ( WL , waiterRecord )
The abstract operation RemoveWaiter takes arguments WL (a WaiterList Record ) and
waiterRecord (a Waiter Record ) and returns
unused . It performs the following steps when called:
Assert :
The surrounding agent is in the
critical section for
WL .
Assert :
WL .[[Waiters]] contains waiterRecord .
Remove waiterRecord from WL .[[Waiters]] .
Return unused .
25.4.3.10 RemoveWaiters ( WL , c )
The abstract operation RemoveWaiters takes arguments WL (a WaiterList Record ) and c (a
non-negative integer or +∞) and returns a List of Waiter
Records . It performs the following steps when called:
Assert :
The surrounding agent is in the
critical section for
WL .
Let len be the number of elements in WL .[[Waiters]] .
Let n be min (c , len ).
Let L be a List whose
elements are the first n elements of WL .[[Waiters]] .
Remove the first n elements of WL .[[Waiters]] .
Return L .
25.4.3.11 SuspendThisAgent ( WL ,
waiterRecord )
The abstract operation SuspendThisAgent takes arguments WL (a WaiterList Record ) and
waiterRecord (a Waiter Record ) and returns
unused . It performs the following steps when called:
Assert :
The surrounding agent is in the
critical section for
WL .
Assert :
WL .[[Waiters]] contains waiterRecord .
Let thisAgent be AgentSignifier ().
Assert :
waiterRecord .[[AgentSignifier]] is
thisAgent .
Assert :
waiterRecord .[[PromiseCapability]] is
blocking .
Assert :
AgentCanSuspend () is
true .
Perform LeaveCriticalSection (WL )
and suspend the surrounding agent until the time is
waiterRecord .[[TimeoutTime]] , performing the
combined operation in such a way that a notification that arrives after the
critical section is exited but
before the suspension takes effect is not lost. The surrounding agent can only wake
from suspension due to a timeout or due to another agent calling NotifyWaiter with arguments
WL and thisAgent (i.e. via a call to
Atomics.notify).
Perform EnterCriticalSection (WL ).
Return unused .
25.4.3.12 NotifyWaiter ( WL , waiterRecord
)
The abstract operation NotifyWaiter takes arguments WL (a WaiterList Record ) and
waiterRecord (a Waiter Record ) and returns
unused . It performs the following steps when called:
Assert :
The surrounding agent is in the
critical section for
WL .
If waiterRecord .[[PromiseCapability]] is
blocking , then
Wake the agent whose signifier is
waiterRecord .[[AgentSignifier]] from
suspension.
NOTE: This causes the agent to resume execution in SuspendThisAgent .
Else if AgentSignifier () is
waiterRecord .[[AgentSignifier]] , then
Let promiseCapability be waiterRecord .[[PromiseCapability]] .
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
waiterRecord .[[Result]] »).
Else,
Perform EnqueueResolveInAgentJob (waiterRecord .[[AgentSignifier]] , waiterRecord .[[PromiseCapability]] , waiterRecord .[[Result]] ).
Return unused .
Note
An agent must
not access another agent 's promise capability in any capacity
beyond passing it to the host .
25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier ,
promiseCapability , resolution )
The abstract operation EnqueueResolveInAgentJob takes arguments agentSignifier (an
agent
signifier ), promiseCapability (a PromiseCapability Record ), and
resolution ("ok" or "timed-out" ) and
returns unused . It performs the following steps when called:
Let resolveJob be a new Job Abstract Closure
with no parameters that captures agentSignifier ,
promiseCapability , and resolution and performs the following
steps when called:
Assert : AgentSignifier () is
agentSignifier .
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
resolution »).
Return unused .
Let realmInTargetAgent be ! GetFunctionRealm (promiseCapability .[[Resolve]] ).
Assert :
agentSignifier is realmInTargetAgent .[[AgentSignifier]] .
Perform HostEnqueueGenericJob (resolveJob ,
realmInTargetAgent ).
Return unused .
25.4.3.14 DoWait ( mode , typedArray ,
index , value , timeout )
The abstract operation DoWait takes arguments mode (sync or
async ), typedArray (an ECMAScript language value ),
index (an ECMAScript language value ),
value (an ECMAScript language value ), and
timeout (an ECMAScript language value ) and
returns either a normal completion
containing either an Object, "not-equal" ,
"timed-out" , or "ok" , or a throw completion . It
performs the following steps when called:
Let taRecord be ? ValidateIntegerTypedArray (typedArray ,
true ).
Let buffer be taRecord .[[Object]] .[[ViewedArrayBuffer]] .
If IsSharedArrayBuffer (buffer )
is false , throw a TypeError exception.
Let i be ? ValidateAtomicAccess (taRecord ,
index ).
Let arrayTypeName be typedArray .[[TypedArrayName]] .
If arrayTypeName is "BigInt64Array" , let v
be ? ToBigInt64 (value ).
Else, let v be ? ToInt32 (value ).
Let q be ? ToNumber (timeout ).
If q is either NaN or
+∞ 𝔽 , let t be +∞; else if q is
-∞ 𝔽 , let t be 0; else let t be
max (ℝ (q ), 0).
If mode is sync and AgentCanSuspend () is
false , throw a TypeError exception.
Let block be buffer .[[ArrayBufferData]] .
Let offset be typedArray .[[ByteOffset]] .
Let byteIndexInBuffer be (i × 4) + offset .
Let WL be GetWaiterList (block ,
byteIndexInBuffer ).
If mode is sync , then
Let promiseCapability be blocking .
Let resultObject be undefined .
Else,
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let resultObject be OrdinaryObjectCreate (%Object.prototype% ).
Perform EnterCriticalSection (WL ).
Let elementType be TypedArrayElementType (typedArray ).
Let w be GetValueFromBuffer (buffer ,
byteIndexInBuffer , elementType , true ,
seq-cst ).
If v ≠ w , then
Perform LeaveCriticalSection (WL ).
If mode is sync , return
"not-equal" .
Perform ! CreateDataPropertyOrThrow (resultObject ,
"async" , false ).
Perform ! CreateDataPropertyOrThrow (resultObject ,
"value" , "not-equal" ).
Return resultObject .
If t = 0 and mode is async , then
NOTE: There is no special handling of synchronous immediate timeouts.
Asynchronous immediate timeouts have special handling in order to fail fast
and avoid unnecessary Promise jobs.
Perform LeaveCriticalSection (WL ).
Perform ! CreateDataPropertyOrThrow (resultObject ,
"async" , false ).
Perform ! CreateDataPropertyOrThrow (resultObject ,
"value" , "timed-out" ).
Return resultObject .
Let thisAgent be AgentSignifier ().
Let now be the time
value (UTC) identifying the current time.
Let additionalTimeout be an implementation-defined
non-negative mathematical value .
Let timeoutTime be ℝ (now ) + t +
additionalTimeout .
NOTE: When t is +∞, timeoutTime is also +∞.
Let waiterRecord be a new Waiter Record { [[AgentSignifier]] : thisAgent , [[PromiseCapability]] : promiseCapability , [[TimeoutTime]] : timeoutTime , [[Result]] : "ok" }.
Perform AddWaiter (WL ,
waiterRecord ).
If mode is sync , then
Perform SuspendThisAgent (WL ,
waiterRecord ).
Else if timeoutTime is finite , then
Perform EnqueueAtomicsWaitAsyncTimeoutJob (WL ,
waiterRecord ).
Perform LeaveCriticalSection (WL ).
If mode is sync , return
waiterRecord .[[Result]] .
Perform ! CreateDataPropertyOrThrow (resultObject ,
"async" , true ).
Perform ! CreateDataPropertyOrThrow (resultObject ,
"value" , promiseCapability .[[Promise]] ).
Return resultObject .
Note
additionalTimeout allows implementations to pad timeouts as necessary,
such as for reducing power consumption or coarsening timer resolution to mitigate
timing attacks. This value may differ from call to call of DoWait.
25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( WL ,
waiterRecord )
The abstract operation EnqueueAtomicsWaitAsyncTimeoutJob takes arguments WL (a
WaiterList Record ) and
waiterRecord (a Waiter Record ) and returns
unused . It performs the following steps when called:
Let timeoutJob be a new Job Abstract Closure
with no parameters that captures WL and waiterRecord and
performs the following steps when called:
Perform EnterCriticalSection (WL ).
If WL .[[Waiters]] contains
waiterRecord , then
Let timeOfJobExecution be the time
value (UTC) identifying the current time.
Assert : ℝ (timeOfJobExecution ) ≥
waiterRecord .[[TimeoutTime]]
(ignoring potential non-monotonicity of time
values ).
Set waiterRecord .[[Result]] to
"timed-out" .
Perform RemoveWaiter (WL ,
waiterRecord ).
Perform NotifyWaiter (WL ,
waiterRecord ).
Perform LeaveCriticalSection (WL ).
Return unused .
Let now be the time
value (UTC) identifying the current time.
Let currentRealm be the current Realm Record .
Perform HostEnqueueTimeoutJob (timeoutJob ,
currentRealm , 𝔽 (waiterRecord .[[TimeoutTime]] ) - now ).
Return unused .
25.4.3.16 AtomicCompareExchangeInSharedBlock ( block ,
byteIndexInBuffer , elementSize , expectedBytes ,
replacementBytes )
The abstract operation AtomicCompareExchangeInSharedBlock takes arguments block (a
Shared Data
Block ), byteIndexInBuffer (an integer ), elementSize (a
non-negative integer ), expectedBytes (a List of byte
values ), and replacementBytes (a List of byte
values ) and returns a List of byte
values . It performs the following steps when called:
Let execution be the [[CandidateExecution]]
field of the surrounding agent 's Agent
Record .
Let eventsRecord be the Agent Events
Record of execution .[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier ().
Let rawBytesRead be a List of length
elementSize whose elements are nondeterministically chosen byte
values .
NOTE: In implementations, rawBytesRead is the result of a load-link, of a
load-exclusive, or of an operand of a read-modify-write instruction on the
underlying hardware. The nondeterminism is a semantic prescription of the memory
model to describe observable behaviour of hardware with weak
consistency.
NOTE: The comparison of the expected value and the read value is performed outside
of the read-modify-write modification
function to avoid needlessly strong synchronization when the
expected value is not equal to the read value.
If ByteListEqual (rawBytesRead ,
expectedBytes ) is true , then
Let second be a new read-modify-write
modification function with parameters
(oldBytes , newBytes ) that captures nothing and
performs the following steps atomically when called:
Return newBytes .
Let event be ReadModifyWriteSharedMemory
{ [[Order]] : seq-cst , [[NoTear]] : true , [[Block]] : block , [[ByteIndex]] : byteIndexInBuffer , [[ElementSize]] : elementSize , [[Payload]] : replacementBytes , [[ModifyOp]] : second }.
Else,
Let event be ReadSharedMemory
{ [[Order]] : seq-cst , [[NoTear]] : true , [[Block]] : block , [[ByteIndex]] : byteIndexInBuffer , [[ElementSize]] : elementSize }.
Append event to eventsRecord .[[EventList]] .
Append Chosen Value Record { [[Event]] : event , [[ChosenValue]] : rawBytesRead } to
execution .[[ChosenValues]] .
Return rawBytesRead .
25.4.3.17 AtomicReadModifyWrite ( typedArray ,
index , value , op )
The abstract operation AtomicReadModifyWrite takes arguments typedArray (an
ECMAScript language value ),
index (an ECMAScript language value ),
value (an ECMAScript language value ), and
op (a read-modify-write modification
function ) and returns either a normal completion
containing either a Number or a BigInt, or a throw completion .
op takes two List of
byte
values arguments and returns a List of byte
values . This operation atomically loads a value, combines it with
another value, and stores the combination. It returns the loaded value. It performs the
following steps when called:
Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray (typedArray ,
index ).
If typedArray .[[ContentType]] is
bigint , let v be ? ToBigInt (value ).
Otherwise, let v be 𝔽 (? ToIntegerOrInfinity (value )).
Perform ? RevalidateAtomicAccess (typedArray ,
byteIndexInBuffer ).
Let buffer be typedArray .[[ViewedArrayBuffer]] .
Let elementType be TypedArrayElementType (typedArray ).
Return GetModifySetValueInBuffer (buffer ,
byteIndexInBuffer , elementType , v , op ).
25.4.3.18 ByteListBitwiseOp ( op , xBytes ,
yBytes )
The abstract operation ByteListBitwiseOp takes arguments op (&,
^, or |), xBytes (a List of byte
values ), and yBytes (a List of byte
values ) and returns a List of byte
values . The operation atomically performs a bitwise operation on all
byte
values of the arguments and returns a List of byte
values . It performs the following steps when called:
Assert :
xBytes and yBytes have the same number of elements.
Let result be a new empty List .
Let i be 0.
For each element xByte of xBytes , do
Let yByte be yBytes [i ].
If op is &, then
Let resultByte be the result of applying the bitwise AND
operation to xByte and yByte .
Else if op is ^, then
Let resultByte be the result of applying the bitwise
exclusive OR (XOR) operation to xByte and
yByte .
Else,
Assert : op is
|.
Let resultByte be the result of applying the bitwise
inclusive OR operation to xByte and yByte .
Set i to i + 1.
Append resultByte to result .
Return result .
25.4.3.19 ByteListEqual ( xBytes , yBytes )
The abstract operation ByteListEqual takes arguments xBytes (a List of byte
values ) and yBytes (a List of byte
values ) and returns a Boolean. It performs the following steps when
called:
If xBytes and yBytes do not have the same number of elements,
return false .
Let i be 0.
For each element xByte of xBytes , do
Let yByte be yBytes [i ].
If xByte ≠ yByte , return false .
Set i to i + 1.
Return true .
25.4.4 Atomics.add ( typedArray , index ,
value )
This function performs the following steps when called:
Let add be a new read-modify-write modification
function with parameters (xBytes , yBytes )
that captures typedArray and performs the following steps atomically when
called:
Let type be TypedArrayElementType (typedArray ).
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent 's Agent
Record .
Let x be RawBytesToNumeric (type ,
xBytes , isLittleEndian ).
Let y be RawBytesToNumeric (type ,
yBytes , isLittleEndian ).
If x is a
Number , then
Let sum be Number::add (x ,
y ).
Else,
Assert : x is a
BigInt .
Let sum be BigInt::add (x ,
y ).
Let sumBytes be NumericToRawBytes (type ,
sum , isLittleEndian ).
Assert : sumBytes ,
xBytes , and yBytes have the same number of elements.
Return sumBytes .
Return ? AtomicReadModifyWrite (typedArray ,
index , value , add ).
25.4.5 Atomics.and ( typedArray , index ,
value )
This function performs the following steps when called:
Let and be a new read-modify-write modification
function with parameters (xBytes , yBytes )
that captures nothing and performs the following steps atomically when called:
Return ByteListBitwiseOp (&,
xBytes , yBytes ).
Return ? AtomicReadModifyWrite (typedArray ,
index , value , and ).
25.4.6 Atomics.compareExchange ( typedArray ,
index , expectedValue , replacementValue )
This function performs the following steps when called:
Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray (typedArray ,
index ).
Let buffer be typedArray .[[ViewedArrayBuffer]] .
Let block be buffer .[[ArrayBufferData]] .
If typedArray .[[ContentType]] is
bigint , then
Let expected be ? ToBigInt (expectedValue ).
Let replacement be ? ToBigInt (replacementValue ).
Else,
Let expected be 𝔽 (? ToIntegerOrInfinity (expectedValue )).
Let replacement be 𝔽 (? ToIntegerOrInfinity (replacementValue )).
Perform ? RevalidateAtomicAccess (typedArray ,
byteIndexInBuffer ).
Let elementType be TypedArrayElementType (typedArray ).
Let elementSize be TypedArrayElementSize (typedArray ).
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding
agent 's Agent Record .
Let expectedBytes be NumericToRawBytes (elementType ,
expected , isLittleEndian ).
Let replacementBytes be NumericToRawBytes (elementType ,
replacement , isLittleEndian ).
If IsSharedArrayBuffer (buffer )
is true , then
Let rawBytesRead be AtomicCompareExchangeInSharedBlock (block ,
byteIndexInBuffer , elementSize , expectedBytes ,
replacementBytes ).
Else,
Let rawBytesRead be a List of
length elementSize whose elements are the sequence of
elementSize bytes starting with
block [byteIndexInBuffer ].
If ByteListEqual (rawBytesRead ,
expectedBytes ) is true , then
Store the individual bytes of replacementBytes into
block , starting at
block [byteIndexInBuffer ].
Return RawBytesToNumeric (elementType ,
rawBytesRead , isLittleEndian ).
25.4.7 Atomics.exchange ( typedArray , index ,
value )
This function performs the following steps when called:
Let second be a new read-modify-write modification
function with parameters (oldBytes ,
newBytes ) that captures nothing and performs the following steps atomically
when called:
Return newBytes .
Return ? AtomicReadModifyWrite (typedArray ,
index , value , second ).
25.4.8 Atomics.isLockFree ( size )
This function performs the following steps when called:
Let n be ? ToIntegerOrInfinity (size ).
Let AR be the Agent Record of the surrounding
agent .
If n = 1, return AR .[[IsLockFree1]] .
If n = 2, return AR .[[IsLockFree2]] .
If n = 4, return true .
If n = 8, return AR .[[IsLockFree8]] .
Return false .
Note
This function is an optimization primitive. The intuition is that if the atomic step of
an atomic primitive (compareExchange, load,
store, add, sub, and,
or, xor, or exchange) on a datum of size
n bytes will be performed without the surrounding agent
acquiring a lock outside the n bytes comprising the datum, then
Atomics.isLockFree(n ) will return true .
High-performance algorithms will use this function to determine whether to use locks or
atomic operations in critical sections . If an atomic
primitive is not lock-free then it is often more efficient for an algorithm to provide
its own locking.
Atomics.isLockFree(4) always returns true as that can be
supported on all known relevant hardware. Being able to assume this will generally
simplify programs.
Regardless of the value returned by this function, all atomic operations are guaranteed
to be atomic. For example, they will never have a visible operation take place in the
middle of the operation (e.g., "tearing").
25.4.9 Atomics.load ( typedArray , index )
This function performs the following steps when called:
Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray (typedArray ,
index ).
Perform ? RevalidateAtomicAccess (typedArray ,
byteIndexInBuffer ).
Let buffer be typedArray .[[ViewedArrayBuffer]] .
Let elementType be TypedArrayElementType (typedArray ).
Return GetValueFromBuffer (buffer ,
byteIndexInBuffer , elementType , true ,
seq-cst ).
25.4.10 Atomics.or ( typedArray , index ,
value )
This function performs the following steps when called:
Let or be a new read-modify-write modification
function with parameters (xBytes , yBytes )
that captures nothing and performs the following steps atomically when called:
Return ByteListBitwiseOp (|,
xBytes , yBytes ).
Return ? AtomicReadModifyWrite (typedArray ,
index , value , or ).
25.4.11 Atomics.store ( typedArray , index ,
value )
This function performs the following steps when called:
Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray (typedArray ,
index ).
If typedArray .[[ContentType]] is
bigint , let v be ? ToBigInt (value ).
Otherwise, let v be 𝔽 (? ToIntegerOrInfinity (value )).
Perform ? RevalidateAtomicAccess (typedArray ,
byteIndexInBuffer ).
Let buffer be typedArray .[[ViewedArrayBuffer]] .
Let elementType be TypedArrayElementType (typedArray ).
Perform SetValueInBuffer (buffer ,
byteIndexInBuffer , elementType , v ,
true , seq-cst ).
Return v .
25.4.12 Atomics.sub ( typedArray , index ,
value )
This function performs the following steps when called:
Let subtract be a new read-modify-write modification
function with parameters (xBytes , yBytes )
that captures typedArray and performs the following steps atomically when
called:
Let type be TypedArrayElementType (typedArray ).
Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent 's Agent
Record .
Let x be RawBytesToNumeric (type ,
xBytes , isLittleEndian ).
Let y be RawBytesToNumeric (type ,
yBytes , isLittleEndian ).
If x is a
Number , then
Let difference be Number::subtract (x ,
y ).
Else,
Assert : x is a
BigInt .
Let difference be BigInt::subtract (x ,
y ).
Let differenceBytes be NumericToRawBytes (type ,
difference , isLittleEndian ).
Assert : differenceBytes ,
xBytes , and yBytes have the same number of elements.
Return differenceBytes .
Return ? AtomicReadModifyWrite (typedArray ,
index , value , subtract ).
25.4.13 Atomics.wait ( typedArray , index ,
value , timeout )
This function puts the surrounding agent in a wait queue and suspends
it until notified or until the wait times out, returning a String differentiating those cases.
It performs the following steps when called:
Return ? DoWait (sync ,
typedArray , index , value , timeout ).
25.4.14 Atomics.waitAsync ( typedArray , index ,
value , timeout )
This function returns a Promise that is resolved when the calling agent is notified or the timeout is reached.
It performs the following steps when called:
Return ? DoWait (async ,
typedArray , index , value , timeout ).
25.4.15 Atomics.notify ( typedArray , index ,
count )
This function notifies some agents that are sleeping in the wait queue.
It performs the following steps when called:
Let taRecord be ? ValidateIntegerTypedArray (typedArray ,
true ).
Let byteIndexInBuffer be ? ValidateAtomicAccess (taRecord ,
index ).
If count is undefined , then
Let c be +∞.
Else,
Let intCount be ? ToIntegerOrInfinity (count ).
Let c be max (intCount , 0).
Let buffer be typedArray .[[ViewedArrayBuffer]] .
Let block be buffer .[[ArrayBufferData]] .
If IsSharedArrayBuffer (buffer )
is false , return +0 𝔽 .
Let WL be GetWaiterList (block ,
byteIndexInBuffer ).
Perform EnterCriticalSection (WL ).
Let S be RemoveWaiters (WL ,
c ).
For each element W of S , do
Perform NotifyWaiter (WL ,
W ).
Perform LeaveCriticalSection (WL ).
Let n be the number of elements in S .
Return 𝔽 (n ).
25.4.16 Atomics.xor ( typedArray , index ,
value )
This function performs the following steps when called:
Let xor be a new read-modify-write modification
function with parameters (xBytes , yBytes )
that captures nothing and performs the following steps atomically when called:
Return ByteListBitwiseOp (^,
xBytes , yBytes ).
Return ? AtomicReadModifyWrite (typedArray ,
index , value , xor ).
25.4.17 Atomics [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "Atomics" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
25.5 The JSON Object
The JSON object:
is %JSON% .
is the initial value of the "JSON" property of the global
object .
is an ordinary
object .
contains two functions, parse and stringify, that are used to parse
and construct JSON texts.
has a [[Prototype]] internal slot whose value is %Object.prototype% .
does not have a [[Construct]] internal method; it cannot be used as a
constructor
with the new operator.
does not have a [[Call]] internal method; it cannot be invoked as a
function.
The JSON Data Interchange Format is defined in ECMA-404. The JSON interchange format used in this
specification is exactly that described by ECMA-404. Conforming implementations of
JSON.parse and JSON.stringify must support the exact interchange format
described in the ECMA-404 specification without any deletions or extensions to the format.
25.5.1 JSON.parse ( text [ , reviver ] )
This function parses a JSON text (a JSON-formatted String) and produces an ECMAScript language value . The JSON
format represents literals, arrays, and objects with a syntax similar to the syntax for
ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects
are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON
strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and
null .
The optional reviver parameter is a function that takes two parameters, key
and value . It can filter and transform the results. It is called with each of the
key /value pairs produced by the parse, and its return value is used
instead of the original value. If it returns what it received, the structure is not modified. If
it returns undefined then the property is deleted from the result.
Let jsonString be ? ToString (text ).
Let unfiltered be ? ParseJSON (jsonString ).
If IsCallable (reviver ) is
true , then
Let root be OrdinaryObjectCreate (%Object.prototype% ).
Let rootName be the empty String.
Perform ! CreateDataPropertyOrThrow (root ,
rootName , unfiltered ).
Return ? InternalizeJSONProperty (root ,
rootName , reviver ).
Else,
Return unfiltered .
The "length" property of this function is 2 𝔽 .
25.5.1.1 ParseJSON ( text )
The abstract operation ParseJSON takes argument text (a String) and returns either
a normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
If StringToCodePoints (text )
is not a valid JSON text as specified in ECMA-404, throw a
SyntaxError exception.
Let scriptString be the string-concatenation of
"(" , text , and ");" .
Let script be ParseText (scriptString ,
Script ).
NOTE: The early
error rules defined in 13.2.5.1
have special handling for the above invocation of ParseText .
Assert :
script is a Parse Node .
Let result be ! Evaluation of script .
NOTE: The PropertyDefinitionEvaluation
semantics defined in 13.2.5.5
have special handling for the above evaluation.
Assert : result is either a String,
a Number, a Boolean, an Object that is defined by either an ArrayLiteral or an
ObjectLiteral , or
null .
Return result .
It is not permitted for a conforming implementation of JSON.parse to extend the
JSON grammars. If an implementation wishes to support a modified or extended JSON
interchange format it must do so by defining a different parse function.
Note 1
Valid JSON text is a subset of the ECMAScript PrimaryExpression syntax. Step
1 verifies that
jsonString conforms to that subset, and step 8 asserts that evaluation
returns a value of an appropriate type.
However, because 13.2.5.5
behaves differently during ParseJSON, the same source text can produce different
results when evaluated as a PrimaryExpression rather than as
JSON. Furthermore, the Early Error for duplicate "__proto__"
properties in object literals, which likewise does not apply during ParseJSON, means
that not all texts accepted by ParseJSON are valid as a PrimaryExpression , despite
matching the grammar.
Note 2
In the case where there are duplicate name Strings within an object, lexically
preceding values for the same key shall be overwritten.
25.5.1.2 InternalizeJSONProperty ( holder ,
name , reviver )
The abstract operation InternalizeJSONProperty takes arguments holder (an Object),
name (a String), and reviver (a function object ) and returns
either a normal completion
containing an ECMAScript language
value or a throw
completion .
Note
This algorithm intentionally does not throw an exception if either [[Delete]] or CreateDataProperty return
false .
It performs the following steps when called:
Let val be ? Get (holder , name ).
If val is an Object , then
Let isArray be ? IsArray (val ).
If isArray is true , then
Let len be ? LengthOfArrayLike (val ).
Let I be 0.
Repeat, while I < len ,
Let prop be ! ToString (𝔽 (I )).
Let newElement be ? InternalizeJSONProperty (val ,
prop , reviver ).
If newElement is undefined ,
then
Perform ? val .[[Delete]] (prop ).
Else,
Perform ? CreateDataProperty (val ,
prop , newElement ).
Set I to I + 1.
Else,
Let keys be ? EnumerableOwnProperties (val ,
key ).
For each String P of keys , do
Let newElement be ? InternalizeJSONProperty (val ,
P , reviver ).
If newElement is undefined ,
then
Perform ? val .[[Delete]] (P ).
Else,
Perform ? CreateDataProperty (val ,
P , newElement ).
Return ? Call (reviver ,
holder , « name , val »).
25.5.2 JSON.stringify ( value [ , replacer [ ,
space ] ] )
This function returns a String in UTF-16 encoded JSON format representing an ECMAScript language value , or
undefined . It can take three parameters. The value parameter is an
ECMAScript language value , which is
usually an object or array, although it can also be a String, Boolean, Number or
null . The optional replacer parameter is either a function that
alters the way objects and arrays are stringified, or an array of Strings and Numbers that acts
as an inclusion list for selecting the object properties that will be stringified. The optional
space parameter is a
String or Number that allows the result to have white space injected into
it to improve human readability.
It performs the following steps when called:
Let stack be a new empty List .
Let indent be the empty String.
Let PropertyList be undefined .
Let ReplacerFunction be undefined .
If replacer is an Object , then
If IsCallable (replacer ) is
true , then
Set ReplacerFunction to replacer .
Else,
Let isArray be ? IsArray (replacer ).
If isArray is true , then
Set PropertyList to a new empty List .
Let len be ? LengthOfArrayLike (replacer ).
Let k be 0.
Repeat, while k < len ,
Let prop be ! ToString (𝔽 (k )).
Let v be ? Get (replacer ,
prop ).
Let item be undefined .
If v is
a String , then
Set item to v .
Else if v is
a Number , then
Set item to ! ToString (v ).
Else if v is an
Object , then
If v has a [[StringData]] or [[NumberData]] internal
slot, set item to ? ToString (v ).
If item is not undefined
and PropertyList does not contain
item , then
Append item to
PropertyList .
Set k to k + 1.
If space is an Object , then
If space has a [[NumberData]] internal slot,
then
Set space to ? ToNumber (space ).
Else if space has a [[StringData]] internal
slot, then
Set space to ? ToString (space ).
If space is a
Number , then
Let spaceMV be ! ToIntegerOrInfinity (space ).
Set spaceMV to min (10, spaceMV ).
If spaceMV < 1, let gap be the empty String; otherwise
let gap be the String value containing spaceMV occurrences
of the code unit 0x0020 (SPACE).
Else if space is a
String , then
If the length of space ≤ 10, let gap be space ;
otherwise let gap be the substring of
space from 0 to 10.
Else,
Let gap be the empty String.
Let wrapper be OrdinaryObjectCreate (%Object.prototype% ).
Perform ! CreateDataPropertyOrThrow (wrapper ,
the empty String, value ).
Let state be the JSON Serialization
Record { [[ReplacerFunction]] :
ReplacerFunction , [[Stack]] : stack , [[Indent]] : indent , [[Gap]] :
gap , [[PropertyList]] :
PropertyList }.
Return ? SerializeJSONProperty (state , the
empty String, wrapper ).
The "length" property of this function is 3 𝔽 .
Note 1
JSON structures are allowed to be nested to any depth, but they must be acyclic. If
value is or contains a cyclic structure, then this function must throw a
TypeError exception. This is an example of a value that cannot be
stringified:
a = [];
a[0 ] = a;
my_text = JSON .stringify (a);
Note 2
Symbolic primitive values are rendered as follows:
The null value is rendered in JSON text as the String value
"null" .
The undefined value is not rendered.
The true value is rendered in JSON text as the String value
"true" .
The false value is rendered in JSON text as the String value
"false" .
Note 3
String values are wrapped in QUOTATION MARK (") code units. The code units
" and \ are escaped with \ prefixes. Control
characters code units are replaced with escape sequences \uHHHH, or with
the shorter forms, \b (BACKSPACE), \f (FORM FEED),
\n (LINE FEED), \r (CARRIAGE RETURN), \t
(CHARACTER TABULATION).
Note 4
Finite numbers
are stringified as if by calling ToString (number ).
NaN and Infinity regardless of sign are
represented as the String value "null" .
Note 5
Values that do not have a JSON representation (such as undefined and
functions) do not produce a String. Instead they produce the
undefined value. In arrays these values are represented as the String
value "null" . In objects an unrepresentable value causes the property
to be excluded from stringification.
Note 6
An object is rendered as U+007B (LEFT CURLY BRACKET) followed by zero or more properties,
separated with a U+002C (COMMA), closed with a U+007D (RIGHT CURLY BRACKET). A property
is a quoted String representing the property name , a U+003A (COLON), and then
the stringified property value. An array is rendered as an opening U+005B (LEFT SQUARE
BRACKET) followed by zero or more values, separated with a U+002C (COMMA), closed with a
U+005D (RIGHT SQUARE BRACKET).
25.5.2.1 JSON Serialization Record
A JSON Serialization Record is
a Record value used to
enable serialization to the JSON format.
JSON Serialization Records have the fields listed in Table 80 .
Table 80: JSON Serialization
Record Fields
Field Name
Value
Meaning
[[ReplacerFunction]]
a function object or
undefined
A function that can supply replacement values for object properties
(from JSON.stringify's replacer parameter).
[[PropertyList]]
either a List
of Strings or undefined
The names of properties to include when serializing a non-array object
(from JSON.stringify's replacer parameter).
[[Gap]]
a String
The unit of indentation (from JSON.stringify's space
parameter).
[[Stack]]
a List
of Objects
The set of nested objects that are in the process of being serialized.
Used to detect cyclic structures.
[[Indent]]
a String
The current indentation.
25.5.2.2 SerializeJSONProperty ( state ,
key , holder )
The abstract operation SerializeJSONProperty takes arguments state (a JSON Serialization Record ),
key (a String), and holder (an Object) and returns either a normal completion
containing either a String or undefined , or a
throw completion . It
performs the following steps when called:
Let value be ? Get (holder , key ).
If value is an Object or value
is a
BigInt , then
Let toJSON be ? GetV (value ,
"toJSON" ).
If IsCallable (toJSON )
is true , then
Set value to ? Call (toJSON ,
value , « key »).
If state .[[ReplacerFunction]] is not
undefined , then
Set value to ? Call (state .[[ReplacerFunction]] , holder , «
key , value »).
If value is an Object , then
If value has a [[NumberData]] internal
slot, then
Set value to ? ToNumber (value ).
Else if value has a [[StringData]]
internal slot, then
Set value to ? ToString (value ).
Else if value has a [[BooleanData]]
internal slot, then
Set value to value .[[BooleanData]] .
Else if value has a [[BigIntData]]
internal slot, then
Set value to value .[[BigIntData]] .
If value is null , return "null" .
If value is true , return "true" .
If value is false , return "false" .
If value is a
String , return QuoteJSONString (value ).
If value is a
Number , then
If value is finite , return ! ToString (value ).
Return "null" .
If value is a
BigInt , throw a TypeError exception.
If value is an Object and IsCallable (value ) is
false , then
Let isArray be ? IsArray (value ).
If isArray is true , return ? SerializeJSONArray (state ,
value ).
Return ? SerializeJSONObject (state ,
value ).
Return undefined .
25.5.2.3 QuoteJSONString ( value )
The abstract operation QuoteJSONString takes argument value (a String) and returns
a String. It wraps value in 0x0022 (QUOTATION MARK) code units and escapes
certain other code units within it. This operation interprets value as a sequence
of UTF-16 encoded code points, as described in 6.1.4 . It performs
the following steps when called:
Let product be the String value consisting solely of the code unit 0x0022
(QUOTATION MARK).
For each code point C of StringToCodePoints (value ),
do
If C is listed in the “Code Point” column of Table 81 ,
then
Set product to the string-concatenation
of product and the escape sequence for C as
specified in the “Escape Sequence” column of the corresponding row.
Else if C has a numeric value less than 0x0020 (SPACE) or
C has the same numeric value as a leading surrogate or
trailing surrogate , then
Let unit be the code unit whose numeric value is the
numeric value of C .
Set product to the string-concatenation
of product and UnicodeEscape (unit ).
Else,
Set product to the string-concatenation
of product and UTF16EncodeCodePoint (C ).
Set product to the string-concatenation of
product and the code unit 0x0022 (QUOTATION MARK).
Return product .
Table 81: JSON Single Character Escape Sequences
Code Point
Unicode Character Name
Escape Sequence
U+0008
BACKSPACE
\b
U+0009
CHARACTER TABULATION
\t
U+000A
LINE FEED (LF)
\n
U+000C
FORM FEED (FF)
\f
U+000D
CARRIAGE RETURN (CR)
\r
U+0022
QUOTATION MARK
\"
U+005C
REVERSE SOLIDUS
\\
25.5.2.4 UnicodeEscape ( C )
The abstract operation UnicodeEscape takes argument C (a code unit) and returns a
String. It represents C as a Unicode escape sequence. It performs the following
steps when called:
Let n be the numeric value of C .
Assert :
n ≤ 0xFFFF.
Let hex be the String representation of n , formatted as a
lowercase hexadecimal number.
Return the string-concatenation of the code
unit 0x005C (REVERSE SOLIDUS), "u" , and StringPad (hex , 4,
"0" , start ).
25.5.2.5 SerializeJSONObject ( state ,
value )
The abstract operation SerializeJSONObject takes arguments state (a JSON Serialization Record ) and
value (an Object) and returns either a normal completion
containing a String or a throw completion . It
serializes an object. It performs the following steps when called:
If state .[[Stack]] contains value ,
throw a TypeError exception because the structure is cyclical.
Append value to state .[[Stack]] .
Let stepBack be state .[[Indent]] .
Set state .[[Indent]] to the string-concatenation of
state .[[Indent]] and state .[[Gap]] .
If state .[[PropertyList]] is not
undefined , then
Let K be state .[[PropertyList]] .
Else,
Let K be ? EnumerableOwnProperties (value ,
key ).
Let partial be a new empty List .
For each element P of K , do
Let strP be ? SerializeJSONProperty (state ,
P , value ).
If strP is not undefined , then
Let member be QuoteJSONString (P ).
Set member to the string-concatenation
of member and ":" .
If state .[[Gap]] is not the
empty String, then
Set member to the string-concatenation
of member and the code unit 0x0020 (SPACE).
Set member to the string-concatenation
of member and strP .
Append member to partial .
If partial is empty, then
Let final be "{}" .
Else,
If state .[[Gap]] is the empty String,
then
Let properties be the String value formed by
concatenating all the element Strings of partial with
each adjacent pair of Strings separated with the code unit 0x002C
(COMMA). A comma is not inserted either before the first String or
after the last String.
Let final be the string-concatenation
of "{" , properties , and
"}" .
Else,
Let separator be the string-concatenation
of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED),
and state .[[Indent]] .
Let properties be the String value formed by
concatenating all the element Strings of partial with
each adjacent pair of Strings separated with separator .
The separator String is not inserted either before the
first String or after the last String.
Let final be the string-concatenation
of "{" , the code unit 0x000A (LINE FEED),
state .[[Indent]] ,
properties , the code unit 0x000A (LINE FEED),
stepBack , and "}" .
Remove the last element of state .[[Stack]] .
Set state .[[Indent]] to stepBack .
Return final .
25.5.2.6 SerializeJSONArray ( state , value
)
The abstract operation SerializeJSONArray takes arguments state (a JSON Serialization Record ) and
value (an ECMAScript language value ) and
returns either a normal completion
containing a String or a throw completion . It
serializes an array. It performs the following steps when called:
If state .[[Stack]] contains value ,
throw a TypeError exception because the structure is cyclical.
Append value to state .[[Stack]] .
Let stepBack be state .[[Indent]] .
Set state .[[Indent]] to the string-concatenation of
state .[[Indent]] and state .[[Gap]] .
Let partial be a new empty List .
Let len be ? LengthOfArrayLike (value ).
Let index be 0.
Repeat, while index < len ,
Let strP be ? SerializeJSONProperty (state ,
! ToString (𝔽 (index )),
value ).
If strP is undefined , then
Append "null" to partial .
Else,
Append strP to partial .
Set index to index + 1.
If partial is empty, then
Let final be "[]" .
Else,
If state .[[Gap]] is the empty String,
then
Let properties be the String value formed by
concatenating all the element Strings of partial with
each adjacent pair of Strings separated with the code unit 0x002C
(COMMA). A comma is not inserted either before the first String or
after the last String.
Let final be the string-concatenation
of "[" , properties , and
"]" .
Else,
Let separator be the string-concatenation
of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED),
and state .[[Indent]] .
Let properties be the String value formed by
concatenating all the element Strings of partial with
each adjacent pair of Strings separated with separator .
The separator String is not inserted either before the
first String or after the last String.
Let final be the string-concatenation
of "[" , the code unit 0x000A (LINE FEED),
state .[[Indent]] ,
properties , the code unit 0x000A (LINE FEED),
stepBack , and "]" .
Remove the last element of state .[[Stack]] .
Set state .[[Indent]] to stepBack .
Return final .
Note
The representation of arrays includes only the elements in the interval
from +0 𝔽 (inclusive) to array.length
(exclusive). Properties whose keys are not array indices are excluded
from the stringification. An array is stringified as an opening LEFT SQUARE BRACKET,
elements separated by COMMA, and a closing RIGHT SQUARE BRACKET.
25.5.3 JSON [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "JSON" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
26 Managing Memory
26.1 WeakRef Objects
A WeakRef is an object that is used to refer
to a target object or symbol without preserving it from garbage collection. WeakRefs can be dereferenced to allow access
to the target value, if the target hasn't been reclaimed by garbage collection.
26.1.1 The WeakRef Constructor
The WeakRef constructor :
is %WeakRef% .
is the initial value of the "WeakRef" property of the global
object .
creates and initializes a new WeakRef when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
may be used as the value in an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
WeakRef behaviour must include a super call to the
WeakRef constructor to create and initialize the subclass
instance with the internal state necessary to support the WeakRef.prototype
built-in methods.
26.1.1.1 WeakRef ( target )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
If CanBeHeldWeakly (target )
is false , throw a TypeError exception.
Let weakRef be ? OrdinaryCreateFromConstructor (NewTarget,
"%WeakRef.prototype%" , « [[WeakRefTarget]] »).
Perform AddToKeptObjects (target ).
Set weakRef .[[WeakRefTarget]] to
target .
Return weakRef .
26.1.2 Properties of the WeakRef Constructor
The WeakRef constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
26.1.2.1 WeakRef.prototype
The initial value of WeakRef.prototype is the WeakRef
prototype object.
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
26.1.3 Properties of the WeakRef Prototype Object
The WeakRef prototype object:
26.1.3.1 WeakRef.prototype.constructor
The initial value of WeakRef.prototype.constructor is %WeakRef% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
26.1.3.2 WeakRef.prototype.deref ( )
This method performs the following steps when called:
Let weakRef be the this value.
Perform ? RequireInternalSlot (weakRef ,
[[WeakRefTarget]] ).
Return WeakRefDeref (weakRef ).
Note
If the WeakRef returns a
target value that is not undefined , then this
target value should not be garbage collected until the current execution
of ECMAScript code has completed. The AddToKeptObjects
operation makes sure read consistency is maintained.
let target = { foo ( ) {} };
let weakRef = new WeakRef (target);
if (weakRef.deref ()) {
weakRef.deref ().foo ();
}
In the above example, if the first deref does not evaluate to
undefined then the second deref cannot either.
26.1.3.3 WeakRef.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "WeakRef" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
26.1.4 WeakRef Abstract Operations
26.1.4.1 WeakRefDeref ( weakRef )
The abstract operation WeakRefDeref takes argument weakRef (a WeakRef ) and returns an ECMAScript language value . It
performs the following steps when called:
Let target be weakRef .[[WeakRefTarget]] .
If target is not empty , then
Perform AddToKeptObjects (target ).
Return target .
Return undefined .
Note
This abstract operation is defined separately from WeakRef.prototype.deref strictly
to make it possible to succinctly define liveness.
26.1.5 Properties of WeakRef Instances
WeakRef instances are ordinary
objects that inherit properties from the WeakRef
prototype . WeakRef instances also have a [[WeakRefTarget]] internal slot.
26.2 FinalizationRegistry Objects
A FinalizationRegistry is an
object that manages registration and unregistration of cleanup operations that are performed when
target objects and symbols are garbage collected.
26.2.1 The FinalizationRegistry Constructor
The FinalizationRegistry constructor :
is %FinalizationRegistry% .
is the initial value of the "FinalizationRegistry" property of the
global
object .
creates and initializes a new FinalizationRegistry when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
may be used as the value in an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
FinalizationRegistry behaviour must include a super call to the
FinalizationRegistry constructor to create and initialize the subclass
instance with the internal state necessary to support the
FinalizationRegistry.prototype built-in methods.
26.2.1.1 FinalizationRegistry ( cleanupCallback )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
If IsCallable (cleanupCallback )
is false , throw a TypeError exception.
Let finalizationRegistry be ? OrdinaryCreateFromConstructor (NewTarget,
"%FinalizationRegistry.prototype%" , « [[Realm]] , [[CleanupCallback]] ,
[[Cells]] »).
Let fn be the active function object .
Set finalizationRegistry .[[Realm]] to
fn .[[Realm]] .
Set finalizationRegistry .[[CleanupCallback]] to
HostMakeJobCallback (cleanupCallback ).
Set finalizationRegistry .[[Cells]] to a new
empty List .
Return finalizationRegistry .
26.2.2 Properties of the FinalizationRegistry Constructor
The FinalizationRegistry
constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
26.2.2.1 FinalizationRegistry.prototype
The initial value of FinalizationRegistry.prototype is the FinalizationRegistry
prototype object.
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
26.2.3 Properties of the FinalizationRegistry Prototype Object
The FinalizationRegistry prototype object:
is %FinalizationRegistry.prototype% .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
is an ordinary
object .
does not have [[Cells]] and [[CleanupCallback]] internal slots.
26.2.3.1 FinalizationRegistry.prototype.constructor
The initial value of FinalizationRegistry.prototype.constructor is %FinalizationRegistry% .
26.2.3.2 FinalizationRegistry.prototype.register (
target , heldValue [ , unregisterToken ] )
This method performs the following steps when called:
Let finalizationRegistry be the this value.
Perform ? RequireInternalSlot (finalizationRegistry ,
[[Cells]] ).
If CanBeHeldWeakly (target )
is false , throw a TypeError exception.
If SameValue (target ,
heldValue ) is true , throw a
TypeError exception.
If CanBeHeldWeakly (unregisterToken )
is false , then
If unregisterToken is not undefined , throw a
TypeError exception.
Set unregisterToken to empty .
Let cell be the Record { [[WeakRefTarget]] : target , [[HeldValue]] : heldValue , [[UnregisterToken]] : unregisterToken }.
Append cell to finalizationRegistry .[[Cells]] .
Return undefined .
Note
Based on the algorithms and definitions in this specification, cell .[[HeldValue]] is live when
finalizationRegistry .[[Cells]] contains
cell ; however, this does not necessarily mean that cell .[[UnregisterToken]] or cell .[[Target]] are live . For example,
registering an object with itself as its unregister token would not keep the object
alive forever.
26.2.3.3 FinalizationRegistry.prototype.unregister (
unregisterToken )
This method performs the following steps when called:
Let finalizationRegistry be the this value.
Perform ? RequireInternalSlot (finalizationRegistry ,
[[Cells]] ).
If CanBeHeldWeakly (unregisterToken )
is false , throw a TypeError exception.
Let removed be false .
For each Record { [[WeakRefTarget]] , [[HeldValue]] ,
[[UnregisterToken]] } cell of
finalizationRegistry .[[Cells]] , do
If cell .[[UnregisterToken]] is not
empty and SameValue (cell .[[UnregisterToken]] , unregisterToken ) is
true , then
Remove cell from finalizationRegistry .[[Cells]] .
Set removed to true .
Return removed .
26.2.3.4 FinalizationRegistry.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "FinalizationRegistry" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
26.2.4 Properties of FinalizationRegistry Instances
FinalizationRegistry
instances are ordinary objects that inherit properties from the
FinalizationRegistry
prototype . FinalizationRegistry
instances also have [[Cells]] and [[CleanupCallback]] internal slots.
27 Control Abstraction Objects
27.1 Iteration
27.1.1 Common Iteration Interfaces
An interface is a set of property keys whose associated values match a
specific specification. Any object that provides all the properties as described by an
interface's specification conforms to that interface. An interface is not represented
by a distinct object. There may be many separately implemented objects that conform to any
interface. An individual object may conform to multiple interfaces.
27.1.1.1 The Iterable Interface
The iterable interface includes the property described in Table 82 :
Table 82: Iterable Interface Required
Properties
27.1.1.2 The Iterator Interface
An object that implements the iterator
interface must include the property in Table 83 . Such
objects may also implement the properties in Table 84 .
Table 83: Iterator Interface Required
Properties
Note 1
Arguments may be passed to the next function but their interpretation
and validity is dependent upon the target iterator. The for-of statement and other
common users of iterators do not pass any arguments, so iterator objects that expect
to be used in such a manner must be prepared to deal with being called with no
arguments.
Table 84: Iterator Interface Optional
Properties
Property
Value
Requirements
"return"
a function that returns an IteratorResult
object
The returned object must conform to the IteratorResult
interface . Invoking this method notifies the
iterator object
that the caller does not intend to make any more next
method calls to the iterator . The
returned IteratorResult
object will typically have a
"done" property whose value is
true , and a "value" property with
the value passed as the argument of the return method.
However, this requirement is not enforced.
"throw"
a function that returns an IteratorResult
object
The returned object must conform to the IteratorResult
interface . Invoking this method notifies the
iterator object
that the caller has detected an error condition. The argument may be
used to identify the error condition and typically will be an exception
object. A typical response is to throw the value passed as
the argument. If the method does not throw, the returned
IteratorResult
object will typically have a
"done" property whose value is
true .
Note 2
Typically callers of these methods should check for their existence before invoking
them. Certain ECMAScript language features including
for-of, yield*, and array destructuring call
these methods after performing an existence check. Most ECMAScript library functions
that accept iterable objects as arguments
also conditionally call them.
27.1.1.3 The Async Iterable Interface
The async iterable interface includes the properties described in
Table
85 :
Table 85: Async Iterable Interface Required
Properties
27.1.1.4 The Async Iterator Interface
An object that implements the async iterator interface must include the properties in Table 86 . Such objects may also
implement the properties in Table 87 .
Table 86: Async Iterator Interface Required
Properties
Property
Value
Requirements
"next"
a function that returns a promise for an IteratorResult
object
The returned promise, when fulfilled, must fulfill with an object
that conforms to the IteratorResult
interface . If a previous call to the
next method of an async
iterator has returned a promise for an
IteratorResult
object whose "done"
property is true , then all subsequent calls to
the next method of that object should also return a
promise for an IteratorResult
object whose "done"
property is true . However, this requirement is
not enforced.
Additionally, the IteratorResult
object that serves as a fulfillment value
should have a "value" property whose value is not
a promise (or "thenable"). However, this requirement is also not
enforced.
Note 1
Arguments may be passed to the next function but their interpretation
and validity is dependent upon the target async iterator. The
for-await-of statement and other common users
of async iterators do not pass any arguments, so async iterator objects that expect
to be used in such a manner must be prepared to deal with being called with no
arguments.
Table 87: Async Iterator Interface Optional
Properties
Property
Value
Requirements
"return"
a function that returns a promise for an IteratorResult
object
The returned promise, when fulfilled, must fulfill with an object
that conforms to the IteratorResult
interface . Invoking this method notifies the
async iterator
object that the caller does not intend to
make any more next method calls to the async
iterator . The returned promise will fulfill
with an IteratorResult
object which will typically have a
"done" property whose value is
true , and a "value" property
with the value passed as the argument of the return
method. However, this requirement is not enforced.
Additionally, the IteratorResult
object that serves as a fulfillment value
should have a "value" property whose value is not
a promise (or "thenable"). If the argument value is used in the
typical manner, then if it is a rejected promise, a promise rejected
with the same reason should be returned; if it is a fulfilled
promise, then its fulfillment value should be used as the
"value" property of the returned promise's
IteratorResult
object fulfillment value. However, these
requirements are also not enforced.
"throw"
a function that returns a promise for an IteratorResult
object
The returned promise, when fulfilled, must fulfill with an object
that conforms to the IteratorResult
interface . Invoking this method notifies the
async iterator
object that the caller has detected an error
condition. The argument may be used to identify the error condition
and typically will be an exception object. A typical response is to
return a rejected promise which rejects with the value passed as the
argument.
If the returned promise is fulfilled, the IteratorResult
object fulfillment value will typically have
a "done" property whose value is
true . Additionally, it should have a
"value" property whose value is not a promise (or
"thenable"), but this requirement is not enforced.
Note 2
Typically callers of these methods should check for their existence before invoking
them. Certain ECMAScript language features including
for-await-of and yield* call
these methods after performing an existence check.
27.1.1.5 The IteratorResult Interface
The IteratorResult
interface includes the properties listed in Table 88 :
Table 88: IteratorResult Interface Properties
Property
Value
Requirements
"done"
a Boolean
This is the result status of an iterator
next method call. If the end of the iterator was
reached "done" is true . If the end
was not reached "done" is false
and a value is available. If a "done" property
(either own or inherited) does not exist, it is considered to have the
value false .
"value"
an ECMAScript language
value
If done is false , this is the current iteration
element value. If done is true , this is the return
value of the iterator , if it
supplied one. If the iterator does not
have a return value, "value" is
undefined . In that case, the
"value" property may be absent from the conforming
object if it does not inherit an explicit "value"
property.
27.1.2 Iterator Helper Objects
An Iterator Helper object is an
ordinary
object that represents a lazy transformation of some specific source
iterator object . There is not a named
constructor
for Iterator Helper objects. Instead, Iterator Helper objects are created by calling certain
methods of Iterator instance objects.
27.1.2.1 The %IteratorHelperPrototype% Object
The %IteratorHelperPrototype% object:
27.1.2.1.1 %IteratorHelperPrototype%.next ( )
Return ? GeneratorResume (this
value, undefined , "Iterator Helper" ).
27.1.2.1.2 %IteratorHelperPrototype%.return ( )
Let O be this value.
Perform ? RequireInternalSlot (O ,
[[UnderlyingIterator]] ).
Assert : O has a [[GeneratorState]] internal slot.
If O .[[GeneratorState]] is
suspended-start , then
Set O .[[GeneratorState]] to
completed .
NOTE: Once a generator enters the completed state it never leaves it and
its associated execution
context is never resumed. Any execution state
associated with O can be discarded at this point.
Perform ? IteratorClose (O .[[UnderlyingIterator]] , NormalCompletion (unused )).
Return CreateIteratorResultObject (undefined ,
true ).
Let C be ReturnCompletion (undefined ).
Return ? GeneratorResumeAbrupt (O ,
C , "Iterator Helper" ).
27.1.2.1.3 %IteratorHelperPrototype% [ %Symbol.toStringTag%
]
The initial value of the %Symbol.toStringTag% property is
the String value "Iterator Helper" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
true }.
27.1.3 Iterator Objects
27.1.3.1 The Iterator Constructor
The Iterator constructor :
is %Iterator% .
is the initial value of the "Iterator" property of the global
object .
is designed to be subclassable. It may be used as the value of an
extends clause of a class definition.
27.1.3.1.1 Iterator ( )
This function performs the following steps when called:
If NewTarget is either undefined or the active function object ,
throw a TypeError exception.
Return ? OrdinaryCreateFromConstructor (NewTarget,
"%Iterator.prototype%" ).
27.1.3.2 Properties of the Iterator Constructor
The Iterator constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
27.1.3.2.1 Iterator.from ( O )
Let iteratorRecord be ? GetIteratorFlattenable (O ,
iterate-string-primitives ).
Let hasInstance be ? OrdinaryHasInstance (%Iterator% ,
iteratorRecord .[[Iterator]] ).
If hasInstance is true , then
Return iteratorRecord .[[Iterator]] .
Let wrapper be OrdinaryObjectCreate (%WrapForValidIteratorPrototype% ,
« [[Iterated]] »).
Set wrapper .[[Iterated]] to
iteratorRecord .
Return wrapper .
27.1.3.2.1.1 The %WrapForValidIteratorPrototype% Object
The %WrapForValidIteratorPrototype% object:
27.1.3.2.1.1.1 %WrapForValidIteratorPrototype%.next
( )
Let O be this value.
Perform ? RequireInternalSlot (O ,
[[Iterated]] ).
Let iteratorRecord be O .[[Iterated]] .
Return ? Call (iteratorRecord .[[NextMethod]] , iteratorRecord .[[Iterator]] ).
27.1.3.2.1.1.2
%WrapForValidIteratorPrototype%.return ( )
Let O be this value.
Perform ? RequireInternalSlot (O ,
[[Iterated]] ).
Let iterator be O .[[Iterated]] .[[Iterator]] .
Assert : iterator
is an Object .
Let returnMethod be ? GetMethod (iterator ,
"return" ).
If returnMethod is undefined , then
Return CreateIteratorResultObject (undefined ,
true ).
Return ? Call (returnMethod ,
iterator ).
27.1.3.2.2 Iterator.prototype
The initial value of Iterator.prototype is the Iterator prototype
object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] :
false , [[Configurable]] :
false }.
27.1.4 Properties of the Iterator Prototype Object
The Iterator prototype object :
Note
All objects defined in this specification that implement the iterator interface also inherit
from %Iterator.prototype%. ECMAScript code may also define objects that inherit from
%Iterator.prototype%. %Iterator.prototype% provides a place where additional methods
that are applicable to all iterator objects may be added.
The following expression is one way that ECMAScript code can access the
%Iterator.prototype% object:
Object .getPrototypeOf (Object .getPrototypeOf ([][Symbol .iterator ]()))
27.1.4.1 Iterator.prototype.constructor
Iterator.prototype.constructor is an accessor property with
attributes { [[Enumerable]] : false , [[Configurable]] : true }. The [[Get]] and [[Set]] attributes are defined
as follows:
27.1.4.1.1 get Iterator.prototype.constructor
The value of the [[Get]] attribute is a built-in function that
requires no arguments. It performs the following steps when called:
Return %Iterator% .
27.1.4.1.2 set Iterator.prototype.constructor
The value of the [[Set]] attribute is a built-in function that
takes an argument v . It performs the following steps when called:
Perform ? SetterThatIgnoresPrototypeProperties (this
value, %Iterator.prototype% ,
"constructor" , v ).
Return undefined .
Note
Unlike the "constructor" property on most built-in prototypes, for
web-compatibility reasons this property must be an accessor.
27.1.4.2 Iterator.prototype.drop ( limit )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
Let numLimit be Completion (ToNumber (limit )).
IfAbruptCloseIterator (numLimit ,
iterated ).
If numLimit is NaN , then
Let error be ThrowCompletion (a newly
created RangeError object).
Return ? IteratorClose (iterated ,
error ).
Let integerLimit be ! ToIntegerOrInfinity (numLimit ).
If integerLimit < 0, then
Let error be ThrowCompletion (a newly
created RangeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let closure be a new Abstract Closure
with no parameters that captures iterated and integerLimit and
performs the following steps when called:
Let remaining be integerLimit .
Repeat, while remaining > 0,
If remaining ≠ +∞, then
Set remaining to remaining - 1.
Let next be ? IteratorStep (iterated ).
If next is done , return ReturnCompletion (undefined ).
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return ReturnCompletion (undefined ).
Let completion be Completion (Yield (value )).
IfAbruptCloseIterator (completion ,
iterated ).
Let result be CreateIteratorFromClosure (closure ,
"Iterator Helper" , %IteratorHelperPrototype% ,
« [[UnderlyingIterator]] »).
Set result .[[UnderlyingIterator]] to
iterated .
Return result .
27.1.4.3 Iterator.prototype.every ( predicate )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (predicate ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return
true .
Let result be Completion (Call (predicate ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (result ,
iterated ).
If ToBoolean (result ) is
false , return ? IteratorClose (iterated ,
NormalCompletion (false )).
Set counter to counter + 1.
27.1.4.4 Iterator.prototype.filter ( predicate )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (predicate ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let closure be a new Abstract Closure
with no parameters that captures iterated and predicate and
performs the following steps when called:
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return ReturnCompletion (undefined ).
Let selected be Completion (Call (predicate ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (selected ,
iterated ).
If ToBoolean (selected )
is true , then
Let completion be Completion (Yield (value )).
IfAbruptCloseIterator (completion ,
iterated ).
Set counter to counter + 1.
Let result be CreateIteratorFromClosure (closure ,
"Iterator Helper" , %IteratorHelperPrototype% ,
« [[UnderlyingIterator]] »).
Set result .[[UnderlyingIterator]] to
iterated .
Return result .
27.1.4.5 Iterator.prototype.find ( predicate )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (predicate ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return
undefined .
Let result be Completion (Call (predicate ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (result ,
iterated ).
If ToBoolean (result ) is
true , return ? IteratorClose (iterated ,
NormalCompletion (value )).
Set counter to counter + 1.
27.1.4.6 Iterator.prototype.flatMap ( mapper )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (mapper ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let closure be a new Abstract Closure
with no parameters that captures iterated and mapper and
performs the following steps when called:
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return ReturnCompletion (undefined ).
Let mapped be Completion (Call (mapper ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (mapped ,
iterated ).
Let innerIterator be Completion (GetIteratorFlattenable (mapped ,
reject-primitives )).
IfAbruptCloseIterator (innerIterator ,
iterated ).
Let innerAlive be true .
Repeat, while innerAlive is true ,
Let innerValue be Completion (IteratorStepValue (innerIterator )).
IfAbruptCloseIterator (innerValue ,
iterated ).
If innerValue is done ,
then
Set innerAlive to
false .
Else,
Let completion be Completion (Yield (innerValue )).
If completion is an abrupt
completion , then
Let backupCompletion be Completion (IteratorClose (innerIterator ,
completion )).
IfAbruptCloseIterator (backupCompletion ,
iterated ).
Return ? IteratorClose (iterated ,
completion ).
Set counter to counter + 1.
Let result be CreateIteratorFromClosure (closure ,
"Iterator Helper" , %IteratorHelperPrototype% ,
« [[UnderlyingIterator]] »).
Set result .[[UnderlyingIterator]] to
iterated .
Return result .
27.1.4.7 Iterator.prototype.forEach ( procedure )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (procedure ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return
undefined .
Let result be Completion (Call (procedure ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (result ,
iterated ).
Set counter to counter + 1.
27.1.4.8 Iterator.prototype.map ( mapper )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (mapper ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let closure be a new Abstract Closure
with no parameters that captures iterated and mapper and
performs the following steps when called:
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return ReturnCompletion (undefined ).
Let mapped be Completion (Call (mapper ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (mapped ,
iterated ).
Let completion be Completion (Yield (mapped )).
IfAbruptCloseIterator (completion ,
iterated ).
Set counter to counter + 1.
Let result be CreateIteratorFromClosure (closure ,
"Iterator Helper" , %IteratorHelperPrototype% ,
« [[UnderlyingIterator]] »).
Set result .[[UnderlyingIterator]] to
iterated .
Return result .
27.1.4.9 Iterator.prototype.reduce ( reducer [ ,
initialValue ] )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (reducer ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
If initialValue is not present, then
Let accumulator be ? IteratorStepValue (iterated ).
If accumulator is done , throw a
TypeError exception.
Let counter be 1.
Else,
Let accumulator be initialValue .
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return
accumulator .
Let result be Completion (Call (reducer ,
undefined , « accumulator , value ,
𝔽 (counter ) »)).
IfAbruptCloseIterator (result ,
iterated ).
Set accumulator to result .
Set counter to counter + 1.
27.1.4.10 Iterator.prototype.some ( predicate )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
If IsCallable (predicate ) is
false , then
Let error be ThrowCompletion (a newly
created TypeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let counter be 0.
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return
false .
Let result be Completion (Call (predicate ,
undefined , « value , 𝔽 (counter ) »)).
IfAbruptCloseIterator (result ,
iterated ).
If ToBoolean (result ) is
true , return ? IteratorClose (iterated ,
NormalCompletion (true )).
Set counter to counter + 1.
27.1.4.11 Iterator.prototype.take ( limit )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be the Iterator Record {
[[Iterator]] : O , [[NextMethod]] : undefined , [[Done]] : false }.
Let numLimit be Completion (ToNumber (limit )).
IfAbruptCloseIterator (numLimit ,
iterated ).
If numLimit is NaN , then
Let error be ThrowCompletion (a newly
created RangeError object).
Return ? IteratorClose (iterated ,
error ).
Let integerLimit be ! ToIntegerOrInfinity (numLimit ).
If integerLimit < 0, then
Let error be ThrowCompletion (a newly
created RangeError object).
Return ? IteratorClose (iterated ,
error ).
Set iterated to ? GetIteratorDirect (O ).
Let closure be a new Abstract Closure
with no parameters that captures iterated and integerLimit and
performs the following steps when called:
Let remaining be integerLimit .
Repeat,
If remaining = 0, then
Return ? IteratorClose (iterated ,
ReturnCompletion (undefined )).
If remaining ≠ +∞, then
Set remaining to remaining - 1.
Let value be ? IteratorStepValue (iterated ).
If value is done , return ReturnCompletion (undefined ).
Let completion be Completion (Yield (value )).
IfAbruptCloseIterator (completion ,
iterated ).
Let result be CreateIteratorFromClosure (closure ,
"Iterator Helper" , %IteratorHelperPrototype% ,
« [[UnderlyingIterator]] »).
Set result .[[UnderlyingIterator]] to
iterated .
Return result .
27.1.4.12 Iterator.prototype.toArray ( )
This method performs the following steps when called:
Let O be the this value.
If O is not an Object , throw a
TypeError exception.
Let iterated be ? GetIteratorDirect (O ).
Let items be a new empty List .
Repeat,
Let value be ? IteratorStepValue (iterated ).
If value is done , return CreateArrayFromList (items ).
Append value to items .
27.1.4.13 Iterator.prototype [ %Symbol.iterator% ] ( )
This function performs the following steps when called:
Return the this value.
The value of the "name" property of this function is
"[Symbol.iterator]" .
27.1.4.14 Iterator.prototype [ %Symbol.toStringTag% ]
Iterator.prototype[%Symbol.toStringTag%] is an accessor property with
attributes { [[Enumerable]] : false , [[Configurable]] : true }. The [[Get]] and [[Set]] attributes are defined
as follows:
27.1.4.14.1 get Iterator.prototype [ %Symbol.toStringTag% ]
The value of the [[Get]] attribute is a built-in function that
requires no arguments. It performs the following steps when called:
Return "Iterator" .
27.1.4.14.2 set Iterator.prototype [ %Symbol.toStringTag% ]
The value of the [[Set]] attribute is a built-in function that
takes an argument v . It performs the following steps when called:
Perform ? SetterThatIgnoresPrototypeProperties (this
value, %Iterator.prototype% ,
%Symbol.toStringTag% ,
v ).
Return undefined .
Note
Unlike the %Symbol.toStringTag% property
on most built-in prototypes, for web-compatibility reasons this property must be an
accessor.
27.1.5 The %AsyncIteratorPrototype% Object
The %AsyncIteratorPrototype% object:
Note
All objects defined in this specification that implement the async iterator interface also
inherit from %AsyncIteratorPrototype%. ECMAScript code may also define objects that
inherit from %AsyncIteratorPrototype%. The %AsyncIteratorPrototype% object provides a
place where additional methods that are applicable to all async iterator objects may be
added.
27.1.5.1 %AsyncIteratorPrototype% [ %Symbol.asyncIterator% ] ( )
This function performs the following steps when called:
Return the this value.
The value of the "name" property of this function is
"[Symbol.asyncIterator]" .
27.1.6 Async-from-Sync Iterator Objects
An Async-from-Sync Iterator
object is an async iterator that adapts a specific
synchronous iterator . Async-from-Sync Iterator objects
are never directly accessible to ECMAScript code. There is not a named constructor for
Async-from-Sync Iterator objects. Instead, Async-from-Sync Iterator objects are created by the
CreateAsyncFromSyncIterator
abstract operation as needed.
27.1.6.1 CreateAsyncFromSyncIterator (
syncIteratorRecord )
The abstract operation CreateAsyncFromSyncIterator takes argument
syncIteratorRecord (an Iterator Record ) and returns an
Iterator Record . It is used to create an
async Iterator Record from a synchronous
Iterator Record . It performs the
following steps when called:
Let asyncIterator be OrdinaryObjectCreate (%AsyncFromSyncIteratorPrototype% ,
« [[SyncIteratorRecord]] »).
Set asyncIterator .[[SyncIteratorRecord]] to
syncIteratorRecord .
Let nextMethod be ! Get (asyncIterator ,
"next" ).
Let iteratorRecord be the Iterator Record {
[[Iterator]] : asyncIterator , [[NextMethod]] : nextMethod , [[Done]] : false }.
Return iteratorRecord .
27.1.6.2 The %AsyncFromSyncIteratorPrototype% Object
The %AsyncFromSyncIteratorPrototype% object:
27.1.6.2.1 %AsyncFromSyncIteratorPrototype%.next ( [
value ] )
Let O be the this value.
Assert : O is an
Object that has a [[SyncIteratorRecord]] internal slot.
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let syncIteratorRecord be O .[[SyncIteratorRecord]] .
If value is present, then
Let result be Completion (IteratorNext (syncIteratorRecord ,
value )).
Else,
Let result be Completion (IteratorNext (syncIteratorRecord )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Return AsyncFromSyncIteratorContinuation (result ,
promiseCapability , syncIteratorRecord ,
true ).
27.1.6.2.2 %AsyncFromSyncIteratorPrototype%.return ( [
value ] )
Let O be the this value.
Assert : O is an
Object that has a [[SyncIteratorRecord]] internal slot.
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let syncIteratorRecord be O .[[SyncIteratorRecord]] .
Let syncIterator be syncIteratorRecord .[[Iterator]] .
Let return be Completion (GetMethod (syncIterator ,
"return" )).
IfAbruptRejectPromise (return ,
promiseCapability ).
If return is undefined , then
Let iteratorResult be CreateIteratorResultObject (value ,
true ).
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
iteratorResult »).
Return promiseCapability .[[Promise]] .
If value is present, then
Let result be Completion (Call (return ,
syncIterator , « value »)).
Else,
Let result be Completion (Call (return ,
syncIterator )).
IfAbruptRejectPromise (result ,
promiseCapability ).
If result is not an Object , then
Perform ! Call (promiseCapability .[[Reject]] , undefined , « a
newly created TypeError object »).
Return promiseCapability .[[Promise]] .
Return AsyncFromSyncIteratorContinuation (result ,
promiseCapability , syncIteratorRecord ,
false ).
27.1.6.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [
value ] )
Note
In this specification,
value is always provided,
but is left optional for consistency with
%AsyncFromSyncIteratorPrototype%.return
( [ value ] ) .
Let O be the this value.
Assert : O is an
Object that has a [[SyncIteratorRecord]] internal slot.
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let syncIteratorRecord be O .[[SyncIteratorRecord]] .
Let syncIterator be syncIteratorRecord .[[Iterator]] .
Let throw be Completion (GetMethod (syncIterator ,
"throw" )).
IfAbruptRejectPromise (throw ,
promiseCapability ).
If throw is undefined , then
NOTE: If syncIterator does not have a throw
method, close it to give it a chance to clean up before we reject the
capability.
Let closeCompletion be NormalCompletion (empty ).
Let result be Completion (IteratorClose (syncIteratorRecord ,
closeCompletion )).
IfAbruptRejectPromise (result ,
promiseCapability ).
NOTE: The next step throws a TypeError to indicate
that there was a protocol violation: syncIterator does not
have a throw method.
NOTE: If closing syncIterator does not throw then the result
of that operation is ignored, even if it yields a rejected promise.
Perform ! Call (promiseCapability .[[Reject]] , undefined , « a
newly created TypeError object »).
Return promiseCapability .[[Promise]] .
If value is present, then
Let result be Completion (Call (throw ,
syncIterator , « value »)).
Else,
Let result be Completion (Call (throw ,
syncIterator )).
IfAbruptRejectPromise (result ,
promiseCapability ).
If result is not an Object , then
Perform ! Call (promiseCapability .[[Reject]] , undefined , « a
newly created TypeError object »).
Return promiseCapability .[[Promise]] .
Return AsyncFromSyncIteratorContinuation (result ,
promiseCapability , syncIteratorRecord ,
true ).
27.1.6.3 Properties of Async-from-Sync Iterator Instances
Async-from-Sync Iterator instances are ordinary
objects that inherit properties from the %AsyncFromSyncIteratorPrototype%
intrinsic object. Async-from-Sync Iterator instances are
initially created with the internal slots listed in Table 89 .
Table 89: Internal Slots of Async-from-Sync Iterator Instances
Internal Slot
Type
Description
[[SyncIteratorRecord]]
an Iterator Record
Represents the original synchronous iterator which is
being adapted.
27.1.6.4 AsyncFromSyncIteratorContinuation ( result ,
promiseCapability , syncIteratorRecord , closeOnRejection )
The abstract operation AsyncFromSyncIteratorContinuation takes arguments result
(an Object), promiseCapability (a PromiseCapability
Record for an intrinsic %Promise% ),
syncIteratorRecord (an Iterator Record ), and
closeOnRejection (a Boolean) and returns a Promise. It performs the following
steps when called:
NOTE: Because promiseCapability is derived from the intrinsic %Promise% , the calls to
promiseCapability .[[Reject]] entailed by the use
IfAbruptRejectPromise below
are guaranteed not to throw.
Let done be Completion (IteratorComplete (result )).
IfAbruptRejectPromise (done ,
promiseCapability ).
Let value be Completion (IteratorValue (result )).
IfAbruptRejectPromise (value ,
promiseCapability ).
Let valueWrapper be Completion (PromiseResolve (%Promise% ,
value )).
If valueWrapper is an abrupt
completion , done is false , and
closeOnRejection is true , then
Set valueWrapper to Completion (IteratorClose (syncIteratorRecord ,
valueWrapper )).
IfAbruptRejectPromise (valueWrapper ,
promiseCapability ).
Let unwrap be a new Abstract Closure
with parameters (v ) that captures done and performs the
following steps when called:
Return CreateIteratorResultObject (v ,
done ).
Let onFulfilled be CreateBuiltinFunction (unwrap ,
1, "" , « »).
NOTE: onFulfilled is used when processing the "value"
property of an IteratorResult object in
order to wait for its value if it is a promise and re-package the result in a new
"unwrapped" IteratorResult object .
If done is true , or if closeOnRejection is
false , then
Let onRejected be undefined .
Else,
Let closeIterator be a new Abstract
Closure with parameters (error ) that
captures syncIteratorRecord and performs the following steps when
called:
Return ? IteratorClose (syncIteratorRecord ,
ThrowCompletion (error )).
Let onRejected be CreateBuiltinFunction (closeIterator ,
1, "" , « »).
NOTE: onRejected is used to close the Iterator when the
"value" property of an IteratorResult
object it yields is a rejected promise.
Perform PerformPromiseThen (valueWrapper ,
onFulfilled , onRejected , promiseCapability ).
Return promiseCapability .[[Promise]] .
27.2 Promise Objects
A Promise is an object that is used as a placeholder for the eventual results of a deferred (and
possibly asynchronous) computation.
Any Promise is in one of three mutually exclusive states: fulfilled , rejected , and
pending :
A promise p is fulfilled if p.then(f, r) will immediately enqueue a
Job to call the function
f.
A promise p is rejected if p.then(f, r) will immediately enqueue a
Job to call the function
r.
A promise is pending if it is neither fulfilled nor rejected.
A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or
rejected.
A promise is resolved if it is settled or if it has been “locked in” to match the state of
another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is
unresolved if it is not resolved. An unresolved promise is always in the pending state. A
resolved promise may be pending, fulfilled or rejected.
27.2.1 Promise Abstract Operations
27.2.1.1 PromiseCapability Records
A PromiseCapability Record is a
Record value used to
encapsulate a Promise or promise-like object along with the functions that are capable of
resolving or rejecting that promise. PromiseCapability Records are produced by the NewPromiseCapability abstract
operation.
PromiseCapability Records have the fields listed in Table 90 .
Table 90: PromiseCapability
Record Fields
Field Name
Value
Meaning
[[Promise]]
an Object
An object that is usable as a promise.
[[Resolve]]
a function object
The function that is used to resolve the given promise.
[[Reject]]
a function object
The function that is used to reject the given promise.
27.2.1.1.1 IfAbruptRejectPromise ( value ,
capability )
IfAbruptRejectPromise is a shorthand for a sequence of algorithm steps that use a
PromiseCapability Record .
An algorithm step of the form:
IfAbruptRejectPromise (value ,
capability ).
means the same thing as:
Assert : value is a Completion
Record .
If value is an abrupt
completion , then
Perform ? Call (capability .[[Reject]] , undefined , «
value .[[Value]] »).
Return capability .[[Promise]] .
Else,
Set value to ! value .
27.2.1.2 PromiseReaction Records
A PromiseReaction Record is a
Record value used to
store information about how a promise should react when it becomes resolved or rejected with
a given value. PromiseReaction Records are created by the PerformPromiseThen abstract operation,
and are used by the Abstract Closure returned by NewPromiseReactionJob .
PromiseReaction Records have the fields listed in Table 91 .
Table 91: PromiseReaction Record
Fields
Field Name
Value
Meaning
[[Capability]]
a PromiseCapability
Record or undefined
The capabilities of the promise for which this record provides a
reaction handler.
[[Type]]
fulfill or reject
The [[Type]] is used when [[Handler]] is empty to
allow for behaviour specific to the settlement type.
[[Handler]]
a JobCallback
Record or empty
The function that should be applied to the incoming value, and whose
return value will govern what happens to the derived promise. If [[Handler]] is empty , a
function that depends on the value of [[Type]]
will be used instead.
27.2.1.3 CreateResolvingFunctions ( promise )
The abstract operation CreateResolvingFunctions takes argument promise (a Promise)
and returns a Record with fields
[[Resolve]] (a function object ) and [[Reject]] (a function object ). It performs the following
steps when called:
Let alreadyResolved be the Record { [[Value]] : false }.
Let stepsResolve be the algorithm steps defined in Promise Resolve
Functions .
Let lengthResolve be the number of non-optional parameters of the
function definition in Promise Resolve
Functions .
Let resolve be CreateBuiltinFunction (stepsResolve ,
lengthResolve , "" , « [[Promise]] , [[AlreadyResolved]] »).
Set resolve .[[Promise]] to promise .
Set resolve .[[AlreadyResolved]] to
alreadyResolved .
Let stepsReject be the algorithm steps defined in Promise Reject
Functions .
Let lengthReject be the number of non-optional parameters of the function
definition in Promise Reject
Functions .
Let reject be CreateBuiltinFunction (stepsReject ,
lengthReject , "" , « [[Promise]] , [[AlreadyResolved]] »).
Set reject .[[Promise]] to promise .
Set reject .[[AlreadyResolved]] to
alreadyResolved .
Return the Record { [[Resolve]] : resolve , [[Reject]] : reject }.
27.2.1.3.1 Promise Reject Functions
A promise reject function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]]
internal slots.
When a promise reject function is called with argument reason , the following
steps are taken:
Let F be the active function
object .
Assert : F has a [[Promise]] internal slot whose value is an
Object .
Let promise be F .[[Promise]] .
Let alreadyResolved be F .[[AlreadyResolved]] .
If alreadyResolved .[[Value]] is
true , return undefined .
Set alreadyResolved .[[Value]] to
true .
Perform RejectPromise (promise ,
reason ).
Return undefined .
The "length" property of a promise reject function is
1 𝔽 .
27.2.1.3.2 Promise Resolve Functions
A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]]
internal slots.
When a promise resolve function is called with argument resolution , the
following steps are taken:
Let F be the active function
object .
Assert : F has a [[Promise]] internal slot whose value is an
Object .
Let promise be F .[[Promise]] .
Let alreadyResolved be F .[[AlreadyResolved]] .
If alreadyResolved .[[Value]] is
true , return undefined .
Set alreadyResolved .[[Value]] to
true .
If SameValue (resolution ,
promise ) is true , then
Let selfResolutionError be a newly created
TypeError object.
Perform RejectPromise (promise ,
selfResolutionError ).
Return undefined .
If resolution is not an Object , then
Perform FulfillPromise (promise ,
resolution ).
Return undefined .
Let then be Completion (Get (resolution ,
"then" )).
If then is an abrupt
completion , then
Perform RejectPromise (promise ,
then .[[Value]] ).
Return undefined .
Let thenAction be then .[[Value]] .
If IsCallable (thenAction )
is false , then
Perform FulfillPromise (promise ,
resolution ).
Return undefined .
Let thenJobCallback be HostMakeJobCallback (thenAction ).
Let job be NewPromiseResolveThenableJob (promise ,
resolution , thenJobCallback ).
Perform HostEnqueuePromiseJob (job .[[Job]] , job .[[Realm]] ).
Return undefined .
The "length" property of a promise resolve function is
1 𝔽 .
27.2.1.4 FulfillPromise ( promise , value )
The abstract operation FulfillPromise takes arguments promise (a Promise) and
value (an ECMAScript language value ) and
returns unused . It performs the following steps when called:
Assert :
The value of promise .[[PromiseState]] is
pending .
Let reactions be promise .[[PromiseFulfillReactions]] .
Set promise .[[PromiseResult]] to
value .
Set promise .[[PromiseFulfillReactions]] to
undefined .
Set promise .[[PromiseRejectReactions]] to
undefined .
Set promise .[[PromiseState]] to
fulfilled .
Perform TriggerPromiseReactions (reactions ,
value ).
Return unused .
27.2.1.5 NewPromiseCapability ( C )
The abstract operation NewPromiseCapability takes argument C (an ECMAScript language value ) and
returns either a normal completion
containing a PromiseCapability
Record or a throw completion . It
attempts to use C as a constructor in the fashion of the built-in
Promise constructor to create a promise and extract its
resolve and reject functions. The promise plus the
resolve and reject functions are used to initialize a new
PromiseCapability Record . It
performs the following steps when called:
If IsConstructor (C ) is
false , throw a TypeError exception.
NOTE: C is assumed to be a constructor function that
supports the parameter conventions of the Promise constructor (see 27.2.3.1 ).
Let resolvingFunctions be the Record { [[Resolve]] : undefined , [[Reject]] : undefined }.
Let executorClosure be a new Abstract Closure
with parameters (resolve , reject ) that captures
resolvingFunctions and performs the following steps when called:
If resolvingFunctions .[[Resolve]] is not
undefined , throw a TypeError
exception.
If resolvingFunctions .[[Reject]] is not
undefined , throw a TypeError
exception.
Set resolvingFunctions .[[Resolve]] to
resolve .
Set resolvingFunctions .[[Reject]] to
reject .
Return undefined .
Let executor be CreateBuiltinFunction (executorClosure ,
2, "" , « »).
Let promise be ? Construct (C , «
executor »).
If IsCallable (resolvingFunctions .[[Resolve]] ) is false , throw a
TypeError exception.
If IsCallable (resolvingFunctions .[[Reject]] ) is false , throw a
TypeError exception.
Return the PromiseCapability
Record { [[Promise]] :
promise , [[Resolve]] :
resolvingFunctions .[[Resolve]] , [[Reject]] : resolvingFunctions .[[Reject]] }.
Note
This abstract operation supports Promise subclassing, as it is generic on any
constructor that calls a passed executor
function argument in the same way as the Promise constructor . It is used to
generalize static methods of the Promise constructor to any
subclass.
27.2.1.6 IsPromise ( x )
The abstract operation IsPromise takes argument x (an ECMAScript language value ) and
returns a Boolean. It checks for the promise brand on an object. It performs the following
steps when called:
If x is not an Object , return
false .
If x does not have a [[PromiseState]] internal
slot, return false .
Return true .
27.2.1.7 RejectPromise ( promise , reason )
The abstract operation RejectPromise takes arguments promise (a Promise) and
reason (an ECMAScript language value ) and
returns unused . It performs the following steps when called:
Assert :
The value of promise .[[PromiseState]] is
pending .
Let reactions be promise .[[PromiseRejectReactions]] .
Set promise .[[PromiseResult]] to
reason .
Set promise .[[PromiseFulfillReactions]] to
undefined .
Set promise .[[PromiseRejectReactions]] to
undefined .
Set promise .[[PromiseState]] to
rejected .
If promise .[[PromiseIsHandled]] is
false , perform HostPromiseRejectionTracker (promise ,
"reject" ).
Perform TriggerPromiseReactions (reactions ,
reason ).
Return unused .
27.2.1.8 TriggerPromiseReactions ( reactions ,
argument )
The abstract operation TriggerPromiseReactions takes arguments reactions (a
List of PromiseReaction Records ) and
argument (an ECMAScript language value ) and
returns unused . It enqueues a new Job for each record in
reactions . Each such Job processes the [[Type]] and
[[Handler]] of the PromiseReaction
Record , and if the [[Handler]] is not
empty , calls it passing the given argument. If the [[Handler]] is empty , the behaviour is
determined by the [[Type]] . It performs the following steps when
called:
For each element reaction of reactions , do
Let job be NewPromiseReactionJob (reaction ,
argument ).
Perform HostEnqueuePromiseJob (job .[[Job]] , job .[[Realm]] ).
Return unused .
27.2.1.9 HostPromiseRejectionTracker ( promise ,
operation )
The host-defined abstract operation
HostPromiseRejectionTracker takes arguments promise (a Promise) and
operation ("reject" or "handle" ) and
returns unused . It allows host environments to track
promise rejections.
The default implementation of HostPromiseRejectionTracker is to return
unused .
Note 1
HostPromiseRejectionTracker is called in two scenarios:
When a promise is rejected without any handlers, it is called with its
operation argument set to "reject" .
When a handler is added to a rejected promise for the first time, it is called
with its operation argument set to "handle" .
A typical implementation of HostPromiseRejectionTracker might try to notify
developers of unhandled rejections, while also being careful to notify them if such
previous notifications are later invalidated by new handlers being attached.
Note 2
If operation is "handle" , an implementation should not
hold a reference to promise in a way that would interfere with garbage
collection. An implementation may hold a reference to promise if
operation is "reject" , since it is expected that
rejections will be rare and not on hot code paths.
27.2.2 Promise Jobs
27.2.2.1 NewPromiseReactionJob ( reaction ,
argument )
The abstract operation NewPromiseReactionJob takes arguments reaction (a PromiseReaction Record ) and
argument (an ECMAScript language value ) and
returns a Record with fields
[[Job]] (a Job Abstract Closure ) and
[[Realm]] (a Realm Record or null ). It
returns a new Job
Abstract Closure that applies the
appropriate handler to the incoming value, and uses the handler's return value to resolve or
reject the derived promise associated with that handler. It performs the following steps
when called:
Let job be a new Job Abstract Closure
with no parameters that captures reaction and argument and
performs the following steps when called:
Let promiseCapability be reaction .[[Capability]] .
Let type be reaction .[[Type]] .
Let handler be reaction .[[Handler]] .
If handler is empty , then
If type is fulfill , then
Let handlerResult be NormalCompletion (argument ).
Else,
Assert :
type is reject .
Let handlerResult be ThrowCompletion (argument ).
Else,
Let handlerResult be Completion (HostCallJobCallback (handler ,
undefined , « argument »)).
If promiseCapability is undefined , then
Assert :
handlerResult is not an abrupt
completion .
Return empty .
Assert : promiseCapability
is a PromiseCapability
Record .
If handlerResult is an abrupt
completion , then
Return ? Call (promiseCapability .[[Reject]] , undefined , «
handlerResult .[[Value]] »).
Else,
Return ? Call (promiseCapability .[[Resolve]] , undefined , «
handlerResult .[[Value]] »).
Let handlerRealm be null .
If reaction .[[Handler]] is not
empty , then
Let getHandlerRealmResult be Completion (GetFunctionRealm (reaction .[[Handler]] .[[Callback]] )).
If getHandlerRealmResult is a normal
completion , set handlerRealm to
getHandlerRealmResult .[[Value]] .
Else, set handlerRealm to the current Realm
Record .
NOTE: handlerRealm is never null unless the
handler is undefined . When the handler is a revoked Proxy
and no ECMAScript code runs, handlerRealm is used to create error
objects.
Return the Record { [[Job]] : job , [[Realm]] :
handlerRealm }.
27.2.2.2 NewPromiseResolveThenableJob (
promiseToResolve , thenable , then )
The abstract operation NewPromiseResolveThenableJob takes arguments
promiseToResolve (a Promise), thenable (an Object), and
then (a JobCallback Record ) and returns a
Record with fields
[[Job]] (a Job Abstract Closure ) and
[[Realm]] (a Realm Record ). It performs the following steps
when called:
Let job be a new Job Abstract Closure
with no parameters that captures promiseToResolve , thenable ,
and then and performs the following steps when called:
Let resolvingFunctions be CreateResolvingFunctions (promiseToResolve ).
Let thenCallResult be Completion (HostCallJobCallback (then ,
thenable , « resolvingFunctions .[[Resolve]] , resolvingFunctions .[[Reject]] »)).
If thenCallResult is an abrupt
completion , then
Return ? Call (resolvingFunctions .[[Reject]] , undefined , «
thenCallResult .[[Value]] »).
Return ! thenCallResult .
Let getThenRealmResult be Completion (GetFunctionRealm (then .[[Callback]] )).
If getThenRealmResult is a normal
completion , let thenRealm be
getThenRealmResult .[[Value]] .
Else, let thenRealm be the current Realm Record .
NOTE: thenRealm is never null . When
then .[[Callback]] is a revoked Proxy and no code
runs, thenRealm is used to create error objects.
Return the Record { [[Job]] : job , [[Realm]] :
thenRealm }.
Note
This Job uses the
supplied thenable and its then method to resolve the given promise.
This process must take place as a Job to ensure that the evaluation of the
then method occurs after evaluation of any surrounding code has
completed.
27.2.3 The Promise Constructor
The Promise constructor :
is %Promise% .
is the initial value of the "Promise" property of the global
object .
creates and initializes a new Promise when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
may be used as the value in an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
Promise behaviour must include a super call to the Promise constructor to
create and initialize the subclass instance with the internal state necessary to support the
Promise and Promise.prototype built-in methods.
27.2.3.1 Promise ( executor )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
If IsCallable (executor ) is
false , throw a TypeError exception.
Let promise be ? OrdinaryCreateFromConstructor (NewTarget,
"%Promise.prototype%" , « [[PromiseState]] , [[PromiseResult]] , [[PromiseFulfillReactions]] , [[PromiseRejectReactions]] , [[PromiseIsHandled]] »).
Set promise .[[PromiseState]] to
pending .
Set promise .[[PromiseResult]] to
empty .
Set promise .[[PromiseFulfillReactions]] to a new
empty List .
Set promise .[[PromiseRejectReactions]] to a new
empty List .
Set promise .[[PromiseIsHandled]] to
false .
Let resolvingFunctions be CreateResolvingFunctions (promise ).
Let completion be Completion (Call (executor ,
undefined , « resolvingFunctions .[[Resolve]] , resolvingFunctions .[[Reject]] »)).
If completion is an abrupt
completion , then
Perform ? Call (resolvingFunctions .[[Reject]] , undefined , «
completion .[[Value]] »).
Return promise .
Note
The executor argument must be a function object . It is
called for initiating and reporting completion of the possibly deferred action
represented by this Promise. The executor is called with two arguments:
resolve and reject . These are functions that may be used by
the executor function to report eventual completion or failure of the
deferred computation. Returning from the executor function does not mean that the
deferred action has been completed but only that the request to eventually perform
the deferred action has been accepted.
The resolve function that is passed to an executor function
accepts a single argument. The executor code may eventually call the
resolve function to indicate that it wishes to resolve the associated
Promise. The argument passed to the resolve function represents the
eventual value of the deferred action and can be either the actual fulfillment value
or another promise which will provide the value if it is fulfilled.
The reject function that is passed to an executor function
accepts a single argument. The executor code may eventually call the
reject function to indicate that the associated Promise is rejected and
will never be fulfilled. The argument passed to the reject function is
used as the rejection value of the promise. Typically it will be an Error object.
The resolve and reject functions passed to an executor function by the
Promise constructor have the capability to
actually resolve and reject the associated promise. Subclasses may have different
constructor behaviour that passes in
customized values for resolve and reject.
27.2.4 Properties of the Promise Constructor
The Promise constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
has the following properties:
27.2.4.1 Promise.all ( iterable )
This function returns a new promise which is fulfilled with an array of fulfillment values
for the passed promises, or rejects with the reason of the first passed promise that
rejects. It resolves all elements of the passed iterable to promises as
it runs this algorithm.
Let C be the this value.
Let promiseCapability be ? NewPromiseCapability (C ).
Let promiseResolve be Completion (GetPromiseResolve (C )).
IfAbruptRejectPromise (promiseResolve ,
promiseCapability ).
Let iteratorRecord be Completion (GetIterator (iterable ,
sync )).
IfAbruptRejectPromise (iteratorRecord ,
promiseCapability ).
Let result be Completion (PerformPromiseAll (iteratorRecord ,
C , promiseCapability , promiseResolve )).
If result is an abrupt
completion , then
If iteratorRecord .[[Done]] is
false , set result to Completion (IteratorClose (iteratorRecord ,
result )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Return ! result .
Note
This function requires its this value to be a constructor function that supports the
parameter conventions of the Promise constructor .
27.2.4.1.1 GetPromiseResolve ( promiseConstructor
)
The abstract operation GetPromiseResolve takes argument promiseConstructor (a
constructor ) and returns either a normal completion
containing a function object or a throw
completion . It performs the following steps when called:
Let promiseResolve be ? Get (promiseConstructor ,
"resolve" ).
If IsCallable (promiseResolve )
is false , throw a TypeError exception.
Return promiseResolve .
27.2.4.1.2 PerformPromiseAll ( iteratorRecord ,
constructor , resultCapability , promiseResolve )
The abstract operation PerformPromiseAll takes arguments iteratorRecord (an
Iterator Record ),
constructor (a constructor ), resultCapability (a
PromiseCapability Record ),
and promiseResolve (a function object ) and returns either a
normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
Let values be a new empty List .
Let remainingElementsCount be the Record {
[[Value]] : 1 }.
Let index be 0.
Repeat,
Let next be ? IteratorStepValue (iteratorRecord ).
If next is done , then
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0, then
Let valuesArray be CreateArrayFromList (values ).
Perform ? Call (resultCapability .[[Resolve]] ,
undefined , «
valuesArray »).
Return resultCapability .[[Promise]] .
Append undefined to values .
Let nextPromise be ? Call (promiseResolve ,
constructor , « next »).
Let steps be the algorithm steps defined in Promise.all
Resolve Element Functions .
Let length be the number of non-optional parameters of the
function definition in Promise.all
Resolve Element Functions .
Let onFulfilled be CreateBuiltinFunction (steps ,
length , "" , « [[AlreadyCalled]] , [[Index]] , [[Values]] ,
[[Capability]] , [[RemainingElements]] »).
Set onFulfilled .[[AlreadyCalled]] to
false .
Set onFulfilled .[[Index]] to
index .
Set onFulfilled .[[Values]] to
values .
Set onFulfilled .[[Capability]] to
resultCapability .
Set onFulfilled .[[RemainingElements]] to
remainingElementsCount .
Set remainingElementsCount .[[Value]]
to remainingElementsCount .[[Value]]
+ 1.
Perform ? Invoke (nextPromise ,
"then" , « onFulfilled ,
resultCapability .[[Reject]] »).
Set index to index + 1.
27.2.4.1.3 Promise.all Resolve Element
Functions
A Promise.all resolve element function is an anonymous built-in function
that is used to resolve a specific Promise.all element. Each
Promise.all resolve element function has [[Index]] , [[Values]] , [[Capability]] , [[RemainingElements]] ,
and [[AlreadyCalled]] internal slots.
When a Promise.all resolve element function is called with argument
x , the following steps are taken:
Let F be the active function
object .
If F .[[AlreadyCalled]] is
true , return undefined .
Set F .[[AlreadyCalled]] to
true .
Let index be F .[[Index]] .
Let values be F .[[Values]] .
Let promiseCapability be F .[[Capability]] .
Let remainingElementsCount be F .[[RemainingElements]] .
Set values [index ] to x .
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0,
then
Let valuesArray be CreateArrayFromList (values ).
Return ? Call (promiseCapability .[[Resolve]] , undefined , «
valuesArray »).
Return undefined .
The "length" property of a Promise.all resolve element
function is 1 𝔽 .
27.2.4.2 Promise.allSettled ( iterable )
This function returns a promise that is fulfilled with an array of promise state snapshots,
but only after all the original promises have settled, i.e. become either fulfilled or
rejected. It resolves all elements of the passed iterable to promises as
it runs this algorithm.
Let C be the this value.
Let promiseCapability be ? NewPromiseCapability (C ).
Let promiseResolve be Completion (GetPromiseResolve (C )).
IfAbruptRejectPromise (promiseResolve ,
promiseCapability ).
Let iteratorRecord be Completion (GetIterator (iterable ,
sync )).
IfAbruptRejectPromise (iteratorRecord ,
promiseCapability ).
Let result be Completion (PerformPromiseAllSettled (iteratorRecord ,
C , promiseCapability , promiseResolve )).
If result is an abrupt
completion , then
If iteratorRecord .[[Done]] is
false , set result to Completion (IteratorClose (iteratorRecord ,
result )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Return ! result .
Note
This function requires its this value to be a constructor function that supports the
parameter conventions of the Promise constructor .
27.2.4.2.1 PerformPromiseAllSettled (
iteratorRecord , constructor , resultCapability ,
promiseResolve )
The abstract operation PerformPromiseAllSettled takes arguments iteratorRecord
(an Iterator Record ),
constructor (a constructor ), resultCapability (a
PromiseCapability Record ),
and promiseResolve (a function object ) and returns either a
normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
Let values be a new empty List .
Let remainingElementsCount be the Record {
[[Value]] : 1 }.
Let index be 0.
Repeat,
Let next be ? IteratorStepValue (iteratorRecord ).
If next is done , then
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0, then
Let valuesArray be CreateArrayFromList (values ).
Perform ? Call (resultCapability .[[Resolve]] ,
undefined , «
valuesArray »).
Return resultCapability .[[Promise]] .
Append undefined to values .
Let nextPromise be ? Call (promiseResolve ,
constructor , « next »).
Let stepsFulfilled be the algorithm steps defined in
Promise.allSettled
Resolve Element Functions .
Let lengthFulfilled be the number of non-optional parameters
of the function definition in Promise.allSettled
Resolve Element Functions .
Let onFulfilled be CreateBuiltinFunction (stepsFulfilled ,
lengthFulfilled , "" , « [[AlreadyCalled]] , [[Index]] , [[Values]] ,
[[Capability]] , [[RemainingElements]] »).
Let alreadyCalled be the Record
{ [[Value]] : false }.
Set onFulfilled .[[AlreadyCalled]] to
alreadyCalled .
Set onFulfilled .[[Index]] to
index .
Set onFulfilled .[[Values]] to
values .
Set onFulfilled .[[Capability]] to
resultCapability .
Set onFulfilled .[[RemainingElements]] to
remainingElementsCount .
Let stepsRejected be the algorithm steps defined in Promise.allSettled
Reject Element Functions .
Let lengthRejected be the number of non-optional parameters
of the function definition in Promise.allSettled
Reject Element Functions .
Let onRejected be CreateBuiltinFunction (stepsRejected ,
lengthRejected , "" , « [[AlreadyCalled]] , [[Index]] , [[Values]] ,
[[Capability]] , [[RemainingElements]] »).
Set onRejected .[[AlreadyCalled]] to
alreadyCalled .
Set onRejected .[[Index]] to
index .
Set onRejected .[[Values]] to
values .
Set onRejected .[[Capability]] to
resultCapability .
Set onRejected .[[RemainingElements]]
to remainingElementsCount .
Set remainingElementsCount .[[Value]]
to remainingElementsCount .[[Value]]
+ 1.
Perform ? Invoke (nextPromise ,
"then" , « onFulfilled ,
onRejected »).
Set index to index + 1.
27.2.4.2.2 Promise.allSettled Resolve Element
Functions
A Promise.allSettled resolve element function is an anonymous built-in
function that is used to resolve a specific Promise.allSettled element.
Each Promise.allSettled resolve element function has [[Index]] , [[Values]] , [[Capability]] , [[RemainingElements]] ,
and [[AlreadyCalled]] internal slots.
When a Promise.allSettled resolve element function is called with argument
x , the following steps are taken:
Let F be the active function
object .
Let alreadyCalled be F .[[AlreadyCalled]] .
If alreadyCalled .[[Value]] is
true , return undefined .
Set alreadyCalled .[[Value]] to
true .
Let index be F .[[Index]] .
Let values be F .[[Values]] .
Let promiseCapability be F .[[Capability]] .
Let remainingElementsCount be F .[[RemainingElements]] .
Let obj be OrdinaryObjectCreate (%Object.prototype% ).
Perform ! CreateDataPropertyOrThrow (obj ,
"status" , "fulfilled" ).
Perform ! CreateDataPropertyOrThrow (obj ,
"value" , x ).
Set values [index ] to obj .
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0,
then
Let valuesArray be CreateArrayFromList (values ).
Return ? Call (promiseCapability .[[Resolve]] , undefined , «
valuesArray »).
Return undefined .
The "length" property of a Promise.allSettled resolve
element function is 1 𝔽 .
27.2.4.2.3 Promise.allSettled Reject Element
Functions
A Promise.allSettled reject element function is an anonymous built-in
function that is used to reject a specific Promise.allSettled element. Each
Promise.allSettled reject element function has [[Index]] , [[Values]] , [[Capability]] , [[RemainingElements]] ,
and [[AlreadyCalled]] internal slots.
When a Promise.allSettled reject element function is called with argument
x , the following steps are taken:
Let F be the active function
object .
Let alreadyCalled be F .[[AlreadyCalled]] .
If alreadyCalled .[[Value]] is
true , return undefined .
Set alreadyCalled .[[Value]] to
true .
Let index be F .[[Index]] .
Let values be F .[[Values]] .
Let promiseCapability be F .[[Capability]] .
Let remainingElementsCount be F .[[RemainingElements]] .
Let obj be OrdinaryObjectCreate (%Object.prototype% ).
Perform ! CreateDataPropertyOrThrow (obj ,
"status" , "rejected" ).
Perform ! CreateDataPropertyOrThrow (obj ,
"reason" , x ).
Set values [index ] to obj .
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0,
then
Let valuesArray be CreateArrayFromList (values ).
Return ? Call (promiseCapability .[[Resolve]] , undefined , «
valuesArray »).
Return undefined .
The "length" property of a Promise.allSettled reject
element function is 1 𝔽 .
27.2.4.3 Promise.any ( iterable )
This function returns a promise that is fulfilled by the first given promise to be fulfilled,
or rejected with an AggregateError holding the rejection reasons if all of the
given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this
algorithm.
Let C be the this value.
Let promiseCapability be ? NewPromiseCapability (C ).
Let promiseResolve be Completion (GetPromiseResolve (C )).
IfAbruptRejectPromise (promiseResolve ,
promiseCapability ).
Let iteratorRecord be Completion (GetIterator (iterable ,
sync )).
IfAbruptRejectPromise (iteratorRecord ,
promiseCapability ).
Let result be Completion (PerformPromiseAny (iteratorRecord ,
C , promiseCapability , promiseResolve )).
If result is an abrupt
completion , then
If iteratorRecord .[[Done]] is
false , set result to Completion (IteratorClose (iteratorRecord ,
result )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Return ! result .
Note
This function requires its this value to be a constructor function that supports the
parameter conventions of the Promise constructor .
27.2.4.3.1 PerformPromiseAny ( iteratorRecord ,
constructor , resultCapability , promiseResolve )
The abstract operation PerformPromiseAny takes arguments iteratorRecord (an
Iterator Record ),
constructor (a constructor ), resultCapability (a
PromiseCapability Record ),
and promiseResolve (a function object ) and returns either a
normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
Let errors be a new empty List .
Let remainingElementsCount be the Record {
[[Value]] : 1 }.
Let index be 0.
Repeat,
Let next be ? IteratorStepValue (iteratorRecord ).
If next is done , then
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0, then
Let error be a newly created
AggregateError object.
Perform ! DefinePropertyOrThrow (error ,
"errors" , PropertyDescriptor { [[Configurable]] :
true , [[Enumerable]] :
false , [[Writable]] :
true , [[Value]] : CreateArrayFromList (errors ) }).
Return ThrowCompletion (error ).
Return resultCapability .[[Promise]] .
Append undefined to errors .
Let nextPromise be ? Call (promiseResolve ,
constructor , « next »).
Let stepsRejected be the algorithm steps defined in Promise.any
Reject Element Functions .
Let lengthRejected be the number of non-optional parameters
of the function definition in Promise.any
Reject Element Functions .
Let onRejected be CreateBuiltinFunction (stepsRejected ,
lengthRejected , "" , « [[AlreadyCalled]] , [[Index]] , [[Errors]] ,
[[Capability]] , [[RemainingElements]] »).
Set onRejected .[[AlreadyCalled]] to
false .
Set onRejected .[[Index]] to
index .
Set onRejected .[[Errors]] to
errors .
Set onRejected .[[Capability]] to
resultCapability .
Set onRejected .[[RemainingElements]]
to remainingElementsCount .
Set remainingElementsCount .[[Value]]
to remainingElementsCount .[[Value]]
+ 1.
Perform ? Invoke (nextPromise ,
"then" , « resultCapability .[[Resolve]] , onRejected »).
Set index to index + 1.
27.2.4.3.2 Promise.any Reject Element Functions
A Promise.any reject element function is an anonymous built-in function that
is used to reject a specific Promise.any element. Each
Promise.any reject element function has [[Index]] ,
[[Errors]] , [[Capability]] , [[RemainingElements]] , and [[AlreadyCalled]] internal slots.
When a Promise.any reject element function is called with argument
x , the following steps are taken:
Let F be the active function
object .
If F .[[AlreadyCalled]] is
true , return undefined .
Set F .[[AlreadyCalled]] to
true .
Let index be F .[[Index]] .
Let errors be F .[[Errors]] .
Let promiseCapability be F .[[Capability]] .
Let remainingElementsCount be F .[[RemainingElements]] .
Set errors [index ] to x .
Set remainingElementsCount .[[Value]] to
remainingElementsCount .[[Value]] - 1.
If remainingElementsCount .[[Value]] = 0,
then
Let error be a newly created
AggregateError object.
Perform ! DefinePropertyOrThrow (error ,
"errors" , PropertyDescriptor { [[Configurable]] : true , [[Enumerable]] : false , [[Writable]] : true , [[Value]] : CreateArrayFromList (errors ) }).
Return ? Call (promiseCapability .[[Reject]] , undefined , «
error »).
Return undefined .
The "length" property of a Promise.any reject element
function is 1 𝔽 .
27.2.4.4 Promise.prototype
The initial value of Promise.prototype is the Promise prototype
object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
27.2.4.5 Promise.race ( iterable )
This function returns a new promise which is settled in the same way as the first passed
promise to settle. It resolves all elements of the passed iterable to promises as
it runs this algorithm.
Let C be the this value.
Let promiseCapability be ? NewPromiseCapability (C ).
Let promiseResolve be Completion (GetPromiseResolve (C )).
IfAbruptRejectPromise (promiseResolve ,
promiseCapability ).
Let iteratorRecord be Completion (GetIterator (iterable ,
sync )).
IfAbruptRejectPromise (iteratorRecord ,
promiseCapability ).
Let result be Completion (PerformPromiseRace (iteratorRecord ,
C , promiseCapability , promiseResolve )).
If result is an abrupt
completion , then
If iteratorRecord .[[Done]] is
false , set result to Completion (IteratorClose (iteratorRecord ,
result )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Return ! result .
Note 1
If the iterable argument yields no values or if none of the promises
yielded by iterable ever settle, then the pending promise returned by
this method will never be settled.
Note 2
This function expects its this value to be a constructor function that supports the
parameter conventions of the Promise constructor . It also
expects that its this value provides a resolve
method.
27.2.4.5.1 PerformPromiseRace ( iteratorRecord ,
constructor , resultCapability , promiseResolve )
The abstract operation PerformPromiseRace takes arguments iteratorRecord (an
Iterator Record ),
constructor (a constructor ), resultCapability (a
PromiseCapability Record ),
and promiseResolve (a function object ) and returns either a
normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
Repeat,
Let next be ? IteratorStepValue (iteratorRecord ).
If next is done , then
Return resultCapability .[[Promise]] .
Let nextPromise be ? Call (promiseResolve ,
constructor , « next »).
Perform ? Invoke (nextPromise ,
"then" , « resultCapability .[[Resolve]] , resultCapability .[[Reject]] »).
27.2.4.6 Promise.reject ( r )
This function returns a new promise rejected with the passed argument.
Let C be the this value.
Let promiseCapability be ? NewPromiseCapability (C ).
Perform ? Call (promiseCapability .[[Reject]] , undefined , «
r »).
Return promiseCapability .[[Promise]] .
Note
This function expects its this value to be a constructor function that supports the
parameter conventions of the Promise constructor .
27.2.4.7 Promise.resolve ( x )
This function returns either a new promise resolved with the passed argument, or the argument
itself if the argument is a promise produced by this constructor .
Let C be the this value.
If C is not an Object , throw a
TypeError exception.
Return ? PromiseResolve (C ,
x ).
Note
This function expects its this value to be a constructor function that supports the
parameter conventions of the Promise constructor .
27.2.4.7.1 PromiseResolve ( C , x )
The abstract operation PromiseResolve takes arguments C (an Object) and
x (an ECMAScript language value )
and returns either a normal
completion containing an ECMAScript language value
or a throw
completion . It returns a new promise resolved with x .
It performs the following steps when called:
If IsPromise (x ) is
true , then
Let xConstructor be ? Get (x ,
"constructor" ).
If SameValue (xConstructor ,
C ) is true , return x .
Let promiseCapability be ? NewPromiseCapability (C ).
Perform ? Call (promiseCapability .[[Resolve]] , undefined , «
x »).
Return promiseCapability .[[Promise]] .
27.2.4.8 Promise.try ( callback , ...args )
This function performs the following steps when called:
Let C be the this value.
If C is not an Object , throw a
TypeError exception.
Let promiseCapability be ? NewPromiseCapability (C ).
Let status be Completion (Call (callback ,
undefined , args )).
If status is an abrupt
completion , then
Perform ? Call (promiseCapability .[[Reject]] , undefined , «
status .[[Value]] »).
Else,
Perform ? Call (promiseCapability .[[Resolve]] , undefined , «
status .[[Value]] »).
Return promiseCapability .[[Promise]] .
Note
This function expects its this value to be a constructor function that supports the
parameter conventions of the Promise constructor .
27.2.4.9 Promise.withResolvers ( )
This function returns an object with three properties: a new promise together with the
resolve and reject functions associated with it.
Let C be the this value.
Let promiseCapability be ? NewPromiseCapability (C ).
Let obj be OrdinaryObjectCreate (%Object.prototype% ).
Perform ! CreateDataPropertyOrThrow (obj ,
"promise" , promiseCapability .[[Promise]] ).
Perform ! CreateDataPropertyOrThrow (obj ,
"resolve" , promiseCapability .[[Resolve]] ).
Perform ! CreateDataPropertyOrThrow (obj ,
"reject" , promiseCapability .[[Reject]] ).
Return obj .
27.2.4.10 get Promise [ %Symbol.species% ]
Promise[%Symbol.species%] is an accessor property whose set
accessor function is undefined . Its get accessor function performs the
following steps when called:
Return the this value.
The value of the "name" property of this function is "get
[Symbol.species]" .
Note
Promise prototype methods normally use their this value's
constructor to create a derived object.
However, a subclass constructor may over-ride that default
behaviour by redefining its %Symbol.species% property.
27.2.5 Properties of the Promise Prototype Object
The Promise prototype object :
is %Promise.prototype% .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
is an ordinary
object .
does not have a [[PromiseState]] internal slot or any of the other
internal slots of Promise instances.
27.2.5.1 Promise.prototype.catch ( onRejected )
This method performs the following steps when called:
Let promise be the this value.
Return ? Invoke (promise ,
"then" , « undefined ,
onRejected »).
27.2.5.2 Promise.prototype.constructor
The initial value of Promise.prototype.constructor is %Promise% .
27.2.5.3 Promise.prototype.finally ( onFinally )
This method performs the following steps when called:
Let promise be the this value.
If promise is not an Object , throw a
TypeError exception.
Let C be ? SpeciesConstructor (promise ,
%Promise% ).
Assert :
IsConstructor (C ) is
true .
If IsCallable (onFinally ) is
false , then
Let thenFinally be onFinally .
Let catchFinally be onFinally .
Else,
Let thenFinallyClosure be a new Abstract Closure with
parameters (value ) that captures onFinally and
C and performs the following steps when called:
Let result be ? Call (onFinally ,
undefined ).
Let p be ? PromiseResolve (C ,
result ).
Let returnValue be a new Abstract Closure
with no parameters that captures value and performs the
following steps when called:
Return value .
Let valueThunk be CreateBuiltinFunction (returnValue ,
0, "" , « »).
Return ? Invoke (p ,
"then" , « valueThunk »).
Let thenFinally be CreateBuiltinFunction (thenFinallyClosure ,
1, "" , « »).
Let catchFinallyClosure be a new Abstract Closure with
parameters (reason ) that captures onFinally and
C and performs the following steps when called:
Let result be ? Call (onFinally ,
undefined ).
Let p be ? PromiseResolve (C ,
result ).
Let throwReason be a new Abstract Closure
with no parameters that captures reason and performs the
following steps when called:
Return ThrowCompletion (reason ).
Let thrower be CreateBuiltinFunction (throwReason ,
0, "" , « »).
Return ? Invoke (p ,
"then" , « thrower »).
Let catchFinally be CreateBuiltinFunction (catchFinallyClosure ,
1, "" , « »).
Return ? Invoke (promise ,
"then" , « thenFinally ,
catchFinally »).
27.2.5.4 Promise.prototype.then ( onFulfilled ,
onRejected )
This method performs the following steps when called:
Let promise be the this value.
If IsPromise (promise ) is
false , throw a TypeError exception.
Let C be ? SpeciesConstructor (promise ,
%Promise% ).
Let resultCapability be ? NewPromiseCapability (C ).
Return PerformPromiseThen (promise ,
onFulfilled , onRejected , resultCapability ).
27.2.5.4.1 PerformPromiseThen ( promise ,
onFulfilled , onRejected [ , resultCapability ] )
The abstract operation PerformPromiseThen takes arguments promise (a Promise),
onFulfilled (an ECMAScript language
value ), and onRejected (an ECMAScript language value )
and optional argument resultCapability (a PromiseCapability Record )
and returns an ECMAScript language value .
It performs the “then” operation on promise using onFulfilled and
onRejected as its settlement actions. If resultCapability is
passed, the result is stored by updating resultCapability 's promise. If it is
not passed, then PerformPromiseThen is being called by a specification-internal
operation where the result does not matter. It performs the following steps when called:
Assert : IsPromise (promise ) is
true .
If resultCapability is not present, then
Set resultCapability to undefined .
If IsCallable (onFulfilled )
is false , then
Let onFulfilledJobCallback be empty .
Else,
Let onFulfilledJobCallback be HostMakeJobCallback (onFulfilled ).
If IsCallable (onRejected )
is false , then
Let onRejectedJobCallback be empty .
Else,
Let onRejectedJobCallback be HostMakeJobCallback (onRejected ).
Let fulfillReaction be the PromiseReaction
Record { [[Capability]] :
resultCapability , [[Type]] :
fulfill , [[Handler]] :
onFulfilledJobCallback }.
Let rejectReaction be the PromiseReaction
Record { [[Capability]] :
resultCapability , [[Type]] :
reject , [[Handler]] :
onRejectedJobCallback }.
If promise .[[PromiseState]] is
pending , then
Append fulfillReaction to promise .[[PromiseFulfillReactions]] .
Append rejectReaction to promise .[[PromiseRejectReactions]] .
Else if promise .[[PromiseState]] is
fulfilled , then
Let value be promise .[[PromiseResult]] .
Let fulfillJob be NewPromiseReactionJob (fulfillReaction ,
value ).
Perform HostEnqueuePromiseJob (fulfillJob .[[Job]] , fulfillJob .[[Realm]] ).
Else,
Assert : The value of
promise .[[PromiseState]] is
rejected .
Let reason be promise .[[PromiseResult]] .
If promise .[[PromiseIsHandled]] is
false , perform HostPromiseRejectionTracker (promise ,
"handle" ).
Let rejectJob be NewPromiseReactionJob (rejectReaction ,
reason ).
Perform HostEnqueuePromiseJob (rejectJob .[[Job]] , rejectJob .[[Realm]] ).
Set promise .[[PromiseIsHandled]] to
true .
If resultCapability is undefined , then
Return undefined .
Else,
Return resultCapability .[[Promise]] .
27.2.5.5 Promise.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "Promise" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.2.6 Properties of Promise Instances
Promise instances are ordinary objects that inherit properties from the
Promise prototype
object (the intrinsic, %Promise.prototype% ).
Promise instances are initially created with the internal slots described in Table 92 .
Table 92: Internal Slots of Promise Instances
Internal Slot
Type
Description
[[PromiseState]]
pending , fulfilled , or
rejected
Governs how a promise will react to incoming calls to its then
method.
[[PromiseResult]]
an ECMAScript language
value or empty
The value with which the promise has been fulfilled or rejected, if any.
empty if and only if the [[PromiseState]] is pending .
[[PromiseFulfillReactions]]
a List
of PromiseReaction
Records
Records
to be processed when/if the promise transitions from the
pending state to the fulfilled
state.
[[PromiseRejectReactions]]
a List
of PromiseReaction
Records
Records
to be processed when/if the promise transitions from the
pending state to the rejected
state.
[[PromiseIsHandled]]
a Boolean
Indicates whether the promise has ever had a fulfillment or rejection
handler; used in unhandled rejection tracking.
27.3 GeneratorFunction Objects
GeneratorFunctions are functions that are usually created by evaluating GeneratorDeclaration s, GeneratorExpression s, and
GeneratorMethod s. They may also
be created by calling the %GeneratorFunction% intrinsic.
Figure 6 (Informative): Generator Objects Relationships
27.3.1 The GeneratorFunction Constructor
The GeneratorFunction constructor :
is %GeneratorFunction% .
is a subclass of Function.
creates and initializes a new GeneratorFunction when called as a function rather than as a
constructor . Thus the function call
GeneratorFunction (…) is equivalent to the object creation expression
new GeneratorFunction (…) with the same arguments.
may be used as the value of an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
GeneratorFunction behaviour must include a super call to the GeneratorFunction
constructor to create and initialize subclass
instances with the internal slots necessary for built-in GeneratorFunction behaviour. All
ECMAScript syntactic forms for defining generator function objects create direct
instances of GeneratorFunction. There is no syntactic means to create instances of
GeneratorFunction subclasses.
27.3.1.1 GeneratorFunction ( ...parameterArgs ,
bodyArg )
The last argument (if any) specifies the body (executable code) of a generator function; any
preceding arguments specify formal parameters.
This function performs the following steps when called:
Let C be the active function object .
If bodyArg is not present, set bodyArg to the empty String.
Return ? CreateDynamicFunction (C ,
NewTarget, generator , parameterArgs ,
bodyArg ).
Note
27.3.2 Properties of the GeneratorFunction Constructor
The GeneratorFunction constructor :
is a standard built-in function object that inherits from the
Function constructor .
has a [[Prototype]] internal slot whose value is %Function% .
has a
"length" property whose value is 1 𝔽 .
has a "name" property whose value is
"GeneratorFunction" .
has the following properties:
27.3.2.1 GeneratorFunction.prototype
The initial value of GeneratorFunction.prototype is the GeneratorFunction
prototype object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
27.3.3 Properties of the GeneratorFunction Prototype Object
The GeneratorFunction prototype object :
27.3.3.1 GeneratorFunction.prototype.constructor
The initial value of GeneratorFunction.prototype.constructor is %GeneratorFunction% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.3.3.2 GeneratorFunction.prototype.prototype
The initial value of GeneratorFunction.prototype.prototype is %GeneratorPrototype% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.3.3.3 GeneratorFunction.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "GeneratorFunction" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.3.4 GeneratorFunction Instances
Every GeneratorFunction instance is an ECMAScript function object and has the
internal slots listed in Table
30 . The value of the [[IsClassConstructor]]
internal slot for all such instances is false .
Each GeneratorFunction instance has the following own properties:
27.3.4.1 length
The specification for the "length" property of Function instances given in
20.2.4.1 also applies to
GeneratorFunction instances.
27.3.4.2 name
The specification for the "name" property of Function instances given in
20.2.4.2 also applies to
GeneratorFunction instances.
27.3.4.3 prototype
Whenever a GeneratorFunction instance is created another ordinary object is also
created and is the initial value of the generator function's "prototype"
property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created Generator when the
generator function object is invoked using [[Call]] .
This property has the attributes { [[Writable]] :
true , [[Enumerable]] : false ,
[[Configurable]] : false }.
Note
Unlike Function instances, the object that is the value of a GeneratorFunction's
"prototype" property does not have a
"constructor" property whose value is the GeneratorFunction
instance.
27.4 AsyncGeneratorFunction Objects
AsyncGeneratorFunctions are functions that are usually created by evaluating AsyncGeneratorDeclaration , AsyncGeneratorExpression ,
and AsyncGeneratorMethod
syntactic productions. They may also be created by calling the %AsyncGeneratorFunction%
intrinsic.
27.4.1 The AsyncGeneratorFunction Constructor
The AsyncGeneratorFunction constructor :
is %AsyncGeneratorFunction% .
is a subclass of Function.
creates and initializes a new AsyncGeneratorFunction when called as a function rather than
as a constructor . Thus the function call
AsyncGeneratorFunction (...) is equivalent to the object creation expression
new AsyncGeneratorFunction (...) with the same arguments.
may be used as the value of an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
AsyncGeneratorFunction behaviour must include a super call to the
AsyncGeneratorFunction constructor to create and initialize subclass
instances with the internal slots necessary for built-in AsyncGeneratorFunction behaviour.
All ECMAScript syntactic forms for defining async generator function
objects create direct instances of AsyncGeneratorFunction. There is
no syntactic means to create instances of AsyncGeneratorFunction subclasses.
27.4.1.1 AsyncGeneratorFunction ( ...parameterArgs ,
bodyArg )
The last argument (if any) specifies the body (executable code) of an async generator
function; any preceding arguments specify formal parameters.
This function performs the following steps when called:
Let C be the active function object .
If bodyArg is not present, set bodyArg to the empty String.
Return ? CreateDynamicFunction (C ,
NewTarget, async-generator , parameterArgs ,
bodyArg ).
Note
27.4.2 Properties of the AsyncGeneratorFunction Constructor
The AsyncGeneratorFunction constructor :
is a standard built-in function object that inherits from the
Function constructor .
has a [[Prototype]] internal slot whose value is %Function% .
has a "length" property
whose value is 1 𝔽 .
has a "name" property whose value is
"AsyncGeneratorFunction" .
has the following properties:
27.4.2.1 AsyncGeneratorFunction.prototype
The initial value of AsyncGeneratorFunction.prototype is the AsyncGeneratorFunction
prototype object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
27.4.3 Properties of the AsyncGeneratorFunction Prototype Object
The AsyncGeneratorFunction prototype object :
27.4.3.1 AsyncGeneratorFunction.prototype.constructor
The initial value of AsyncGeneratorFunction.prototype.constructor is %AsyncGeneratorFunction% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.4.3.2 AsyncGeneratorFunction.prototype.prototype
The initial value of AsyncGeneratorFunction.prototype.prototype is %AsyncGeneratorPrototype% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.4.3.3 AsyncGeneratorFunction.prototype [ %Symbol.toStringTag%
]
The initial value of the %Symbol.toStringTag% property is the
String value "AsyncGeneratorFunction" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.4.4 AsyncGeneratorFunction Instances
Every AsyncGeneratorFunction instance is an ECMAScript function object and has the
internal slots listed in Table
30 . The value of the [[IsClassConstructor]]
internal slot for all such instances is false .
Each AsyncGeneratorFunction instance has the following own properties:
27.4.4.1 length
The value of the "length" property is an integral Number that indicates
the typical number of arguments expected by the AsyncGeneratorFunction. However, the
language permits the function to be invoked with some other number of arguments. The
behaviour of an AsyncGeneratorFunction when invoked on a number of arguments other than the
number specified by its "length" property depends on the function.
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.4.4.2 name
The specification for the "name" property of Function instances given in
20.2.4.2 also applies to
AsyncGeneratorFunction instances.
27.4.4.3 prototype
Whenever an AsyncGeneratorFunction instance is created, another ordinary
object is also created and is the initial value of the async
generator function's "prototype" property. The value of the prototype
property is used to initialize the [[Prototype]] internal slot of a
newly created AsyncGenerator when the generator function object is invoked
using [[Call]] .
This property has the attributes { [[Writable]] :
true , [[Enumerable]] : false ,
[[Configurable]] : false }.
Note
Unlike function instances, the object that is the value of an
AsyncGeneratorFunction's "prototype" property does not have a
"constructor" property whose value is the AsyncGeneratorFunction
instance.
27.5 Generator Objects
A Generator is created by calling a generator function and conforms to both the iterator
interface and the iterable interface .
Generator instances directly inherit properties from the initial value of the
"prototype" property of the generator function that created the instance.
Generator instances indirectly inherit properties from %GeneratorPrototype% .
27.5.1 The %GeneratorPrototype% Object
The %GeneratorPrototype% object:
is %GeneratorFunction.prototype.prototype% .
is an ordinary
object .
is not a Generator instance and does not have a [[GeneratorState]]
internal slot.
has a [[Prototype]] internal slot whose value is %Iterator.prototype% .
has properties that are indirectly inherited by all Generator instances.
27.5.1.1 %GeneratorPrototype%.constructor
The initial value of %GeneratorPrototype% .constructor
is %GeneratorFunction.prototype% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.5.1.2 %GeneratorPrototype%.next ( value )
Return ? GeneratorResume (this
value, value , empty ).
27.5.1.3 %GeneratorPrototype%.return ( value )
This method performs the following steps when called:
Let g be the this value.
Let C be ReturnCompletion (value ).
Return ? GeneratorResumeAbrupt (g ,
C , empty ).
27.5.1.4 %GeneratorPrototype%.throw ( exception )
This method performs the following steps when called:
Let g be the this value.
Let C be ThrowCompletion (exception ).
Return ? GeneratorResumeAbrupt (g ,
C , empty ).
27.5.1.5 %GeneratorPrototype% [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "Generator" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.5.2 Properties of Generator Instances
Generator instances are initially created with the internal slots described in Table 93 .
Table 93: Internal Slots of Generator Instances
Internal Slot
Type
Description
[[GeneratorState]]
suspended-start ,
suspended-yield , executing , or
completed
The current execution state of the generator.
[[GeneratorContext]]
an execution context
The execution context that
is used when executing the code of this generator.
[[GeneratorBrand]]
a String or empty
A brand used to distinguish different kinds of generators. The [[GeneratorBrand]] of generators declared by
ECMAScript source text is
always empty .
27.5.3 Generator Abstract Operations
27.5.3.1 GeneratorStart ( generator ,
generatorBody )
The abstract operation GeneratorStart takes arguments generator (a Generator) and
generatorBody (a FunctionBody Parse
Node or an Abstract Closure with no parameters) and
returns unused . It performs the following steps when called:
Assert :
The value of generator .[[GeneratorState]] is
suspended-start .
Let genContext be the running execution
context .
Set the Generator component of genContext to generator .
Let closure be a new Abstract Closure
with no parameters that captures generatorBody and performs the following
steps when called:
Let acGenContext be the running execution
context .
Let acGenerator be the Generator component of
acGenContext .
If generatorBody is a Parse
Node , then
Let result be Completion (Evaluation of
generatorBody ).
Else,
Assert :
generatorBody is an Abstract Closure
with no parameters.
Let result be Completion (generatorBody ()).
Assert : If we return here, the
generator either threw an exception or performed either an implicit or
explicit return.
Remove acGenContext from the execution context
stack and restore the execution context that
is at the top of the execution context
stack as the running execution
context .
Set acGenerator .[[GeneratorState]] to
completed .
NOTE: Once a generator enters the completed state it
never leaves it and its associated execution
context is never resumed. Any execution state
associated with acGenerator can be discarded at this point.
If result is a normal
completion , then
Let resultValue be undefined .
Else if result is a return
completion , then
Let resultValue be result .[[Value]] .
Else,
Assert : result is a
throw
completion .
Return ? result .
Return CreateIteratorResultObject (resultValue ,
true ).
Set the code evaluation state of genContext such that when evaluation is
resumed for that execution context ,
closure will be called with no arguments.
Set generator .[[GeneratorContext]] to
genContext .
Return unused .
27.5.3.2 GeneratorValidate ( generator ,
generatorBrand )
The abstract operation GeneratorValidate takes arguments generator (an ECMAScript language value ) and
generatorBrand (a String or empty ) and returns either a
normal completion
containing one of suspended-start ,
suspended-yield , or completed , or a throw completion . It
performs the following steps when called:
Perform ? RequireInternalSlot (generator ,
[[GeneratorState]] ).
Perform ? RequireInternalSlot (generator ,
[[GeneratorBrand]] ).
If generator .[[GeneratorBrand]] is not
generatorBrand , throw a TypeError exception.
Assert :
generator also has a [[GeneratorContext]]
internal slot.
Let state be generator .[[GeneratorState]] .
If state is executing , throw a
TypeError exception.
Return state .
27.5.3.3 GeneratorResume ( generator ,
value , generatorBrand )
The abstract operation GeneratorResume takes arguments generator (an ECMAScript language value ),
value (an ECMAScript language value or
empty ), and generatorBrand (a String or
empty ) and returns either a normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
Let state be ? GeneratorValidate (generator ,
generatorBrand ).
If state is completed , return CreateIteratorResultObject (undefined ,
true ).
Assert :
state is either suspended-start or
suspended-yield .
Let genContext be generator .[[GeneratorContext]] .
Let methodContext be the running execution
context .
Suspend methodContext .
Set generator .[[GeneratorState]] to
executing .
Push genContext onto the execution context
stack ; genContext is now the running execution context .
Resume the suspended evaluation of
genContext using NormalCompletion (value )
as the result of the operation that suspended it. Let result be the value
returned by the resumed computation.
Assert :
When we return here, genContext has already been removed from the
execution context stack and
methodContext is the currently running execution context .
Return ? result .
27.5.3.4 GeneratorResumeAbrupt ( generator ,
abruptCompletion , generatorBrand )
The abstract operation GeneratorResumeAbrupt takes arguments generator (an
ECMAScript language value ),
abruptCompletion (a return
completion or a throw completion ),
and generatorBrand (a String or empty ) and returns either
a normal completion
containing an ECMAScript language
value or a throw
completion . It performs the following steps when called:
Let state be ? GeneratorValidate (generator ,
generatorBrand ).
If state is suspended-start , then
Set generator .[[GeneratorState]] to
completed .
NOTE: Once a generator enters the completed state it
never leaves it and its associated execution
context is never resumed. Any execution state
associated with generator can be discarded at this point.
Set state to completed .
If state is completed , then
If abruptCompletion is a return
completion , then
Return CreateIteratorResultObject (abruptCompletion .[[Value]] , true ).
Return ? abruptCompletion .
Assert :
state is suspended-yield .
Let genContext be generator .[[GeneratorContext]] .
Let methodContext be the running execution
context .
Suspend methodContext .
Set generator .[[GeneratorState]] to
executing .
Push genContext onto the execution context
stack ; genContext is now the running execution context .
Resume the suspended evaluation of
genContext using abruptCompletion as the result of
the operation that suspended it. Let result be the Completion
Record returned by the resumed computation.
Assert :
When we return here, genContext has already been removed from the
execution context stack and
methodContext is the currently running execution context .
Return ? result .
27.5.3.5 GetGeneratorKind ( )
The abstract operation GetGeneratorKind takes no arguments and returns
non-generator , sync , or
async . It performs the following steps when called:
Let genContext be the running execution
context .
If genContext does not have a Generator component, return
non-generator .
Let generator be the Generator component of genContext .
If generator has an [[AsyncGeneratorState]]
internal slot, return async .
Else, return sync .
27.5.3.6 GeneratorYield ( iteratorResult )
The abstract operation GeneratorYield takes argument iteratorResult (an Object
that conforms to the IteratorResult interface ) and
returns either a normal completion
containing an ECMAScript language
value or an abrupt completion .
It performs the following steps when called:
Let genContext be the running execution
context .
Assert :
genContext is the execution
context of a generator.
Let generator be the value of the Generator component of
genContext .
Assert :
GetGeneratorKind () is
sync .
Set generator .[[GeneratorState]] to
suspended-yield .
Remove genContext from the execution context
stack and restore the execution context that is at
the top of the execution context stack as
the running execution context .
Let callerContext be the running execution
context .
Resume callerContext passing NormalCompletion (iteratorResult ).
If genContext is ever resumed again, let resumptionValue be
the Completion
Record with which it is resumed.
Assert : If
control reaches here, then genContext is the running execution context
again.
Return resumptionValue .
27.5.3.7 Yield ( value )
The abstract operation Yield takes argument value (an ECMAScript language value ) and
returns either a normal completion
containing an ECMAScript language
value or an abrupt completion .
It performs the following steps when called:
Let generatorKind be GetGeneratorKind ().
If generatorKind is async , return ? AsyncGeneratorYield (? Await (value )).
Otherwise, return ? GeneratorYield (CreateIteratorResultObject (value ,
false )).
27.5.3.8 CreateIteratorFromClosure ( closure ,
generatorBrand , generatorPrototype [ , extraSlots ] )
The abstract operation CreateIteratorFromClosure takes arguments closure (an
Abstract Closure with no parameters),
generatorBrand (a String or empty ), and
generatorPrototype (an Object) and optional argument extraSlots (a
List of names of
internal slots) and returns a Generator. It performs the following steps when called:
NOTE: closure can contain uses of the Yield operation to yield an
IteratorResult object .
If extraSlots is not present, set extraSlots to a new empty
List .
Let internalSlotsList be the list-concatenation
of extraSlots and « [[GeneratorState]] , [[GeneratorContext]] , [[GeneratorBrand]] ».
Let generator be OrdinaryObjectCreate (generatorPrototype ,
internalSlotsList ).
Set generator .[[GeneratorBrand]] to
generatorBrand .
Set generator .[[GeneratorState]] to
suspended-start .
Let callerContext be the running execution
context .
Let calleeContext be a new execution
context .
Set the Function of calleeContext to null .
Set the Realm of calleeContext to the current Realm
Record .
Set the ScriptOrModule of calleeContext to callerContext 's
ScriptOrModule.
If callerContext is not already suspended, suspend
callerContext .
Push calleeContext onto the execution context
stack ; calleeContext is now the running execution context .
Perform GeneratorStart (generator ,
closure ).
Remove calleeContext from the execution context
stack and restore callerContext as the running execution context .
Return generator .
27.6 AsyncGenerator Objects
An AsyncGenerator is created by calling an async generator function and conforms to both the
async iterator interface and the
async iterable interface .
AsyncGenerator instances directly inherit properties from the initial value of the
"prototype" property of the async generator function that created the instance.
AsyncGenerator instances indirectly inherit properties from %AsyncGeneratorPrototype% .
27.6.1 The %AsyncGeneratorPrototype% Object
The %AsyncGeneratorPrototype% object:
is %AsyncGeneratorFunction.prototype.prototype% .
is an ordinary
object .
is not an AsyncGenerator instance and does not have an [[AsyncGeneratorState]] internal slot.
has a [[Prototype]] internal slot whose value is %AsyncIteratorPrototype% .
has properties that are indirectly inherited by all AsyncGenerator instances.
27.6.1.1 %AsyncGeneratorPrototype%.constructor
The initial value of %AsyncGeneratorPrototype% .constructor
is %AsyncGeneratorFunction.prototype% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.6.1.2 %AsyncGeneratorPrototype%.next ( value )
Let generator be the this value.
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let result be Completion (AsyncGeneratorValidate (generator ,
empty )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Let state be generator .[[AsyncGeneratorState]] .
If state is completed , then
Let iteratorResult be CreateIteratorResultObject (undefined ,
true ).
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
iteratorResult »).
Return promiseCapability .[[Promise]] .
Let completion be NormalCompletion (value ).
Perform AsyncGeneratorEnqueue (generator ,
completion , promiseCapability ).
If state is either suspended-start or
suspended-yield , then
Perform AsyncGeneratorResume (generator ,
completion ).
Else,
Assert : state is either
executing or draining-queue .
Return promiseCapability .[[Promise]] .
27.6.1.3 %AsyncGeneratorPrototype%.return ( value )
Let generator be the this value.
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let result be Completion (AsyncGeneratorValidate (generator ,
empty )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Let completion be ReturnCompletion (value ).
Perform AsyncGeneratorEnqueue (generator ,
completion , promiseCapability ).
Let state be generator .[[AsyncGeneratorState]] .
If state is either suspended-start or
completed , then
Set generator .[[AsyncGeneratorState]] to
draining-queue .
Perform AsyncGeneratorAwaitReturn (generator ).
Else if state is suspended-yield , then
Perform AsyncGeneratorResume (generator ,
completion ).
Else,
Assert : state is either
executing or draining-queue .
Return promiseCapability .[[Promise]] .
27.6.1.4 %AsyncGeneratorPrototype%.throw ( exception
)
Let generator be the this value.
Let promiseCapability be ! NewPromiseCapability (%Promise% ).
Let result be Completion (AsyncGeneratorValidate (generator ,
empty )).
IfAbruptRejectPromise (result ,
promiseCapability ).
Let state be generator .[[AsyncGeneratorState]] .
If state is suspended-start , then
Set generator .[[AsyncGeneratorState]] to
completed .
Set state to completed .
If state is completed , then
Perform ! Call (promiseCapability .[[Reject]] , undefined , «
exception »).
Return promiseCapability .[[Promise]] .
Let completion be ThrowCompletion (exception ).
Perform AsyncGeneratorEnqueue (generator ,
completion , promiseCapability ).
If state is suspended-yield , then
Perform AsyncGeneratorResume (generator ,
completion ).
Else,
Assert : state is either
executing or draining-queue .
Return promiseCapability .[[Promise]] .
27.6.1.5 %AsyncGeneratorPrototype% [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "AsyncGenerator" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.6.2 Properties of AsyncGenerator Instances
AsyncGenerator instances are initially created with the internal slots described below:
Table 94: Internal Slots of AsyncGenerator Instances
Internal Slot
Type
Description
[[AsyncGeneratorState]]
suspended-start ,
suspended-yield , executing ,
draining-queue , or completed
The current execution state of the async generator.
[[AsyncGeneratorContext]]
an execution context
The execution context that
is used when executing the code of this async generator.
[[AsyncGeneratorQueue]]
a List
of AsyncGeneratorRequest
Records
Records
which represent requests to resume the async generator. Except during state
transitions, it is non-empty if and only if [[AsyncGeneratorState]] is either
executing or draining-queue .
[[GeneratorBrand]]
a String or empty
A brand used to distinguish different kinds of async generators. The [[GeneratorBrand]] of async generators declared by
ECMAScript source text is
always empty .
27.6.3 AsyncGenerator Abstract Operations
27.6.3.1 AsyncGeneratorRequest Records
An AsyncGeneratorRequest is a
Record value used to
store information about how an async generator should be resumed and contains capabilities
for fulfilling or rejecting the corresponding promise.
They have the following fields:
Table 95: AsyncGeneratorRequest Record Fields
27.6.3.2 AsyncGeneratorStart ( generator ,
generatorBody )
The abstract operation AsyncGeneratorStart takes arguments generator (an
AsyncGenerator) and generatorBody (a FunctionBody Parse
Node or an Abstract Closure with no parameters) and
returns unused . It performs the following steps when called:
Assert :
generator .[[AsyncGeneratorState]] is
suspended-start .
Let genContext be the running execution
context .
Set the Generator component of genContext to generator .
Let closure be a new Abstract Closure
with no parameters that captures generatorBody and performs the following
steps when called:
Let acGenContext be the running execution
context .
Let acGenerator be the Generator component of
acGenContext .
If generatorBody is a Parse
Node , then
Let result be Completion (Evaluation of
generatorBody ).
Else,
Assert :
generatorBody is an Abstract Closure
with no parameters.
Let result be Completion (generatorBody ()).
Assert : If we return here, the async
generator either threw an exception or performed either an implicit or
explicit return.
Remove acGenContext from the execution context
stack and restore the execution context that
is at the top of the execution context
stack as the running execution
context .
Set acGenerator .[[AsyncGeneratorState]]
to draining-queue .
If result is a normal
completion , set result to NormalCompletion (undefined ).
If result is a return
completion , set result to NormalCompletion (result .[[Value]] ).
Perform AsyncGeneratorCompleteStep (acGenerator ,
result , true ).
Perform AsyncGeneratorDrainQueue (acGenerator ).
Return undefined .
Set the code evaluation state of genContext such that when evaluation is
resumed for that execution context ,
closure will be called with no arguments.
Set generator .[[AsyncGeneratorContext]] to
genContext .
Set generator .[[AsyncGeneratorQueue]] to a new
empty List .
Return unused .
27.6.3.3 AsyncGeneratorValidate ( generator ,
generatorBrand )
The abstract operation AsyncGeneratorValidate takes arguments generator (an
ECMAScript language value ) and
generatorBrand (a String or empty ) and returns either a
normal completion
containing unused or a throw completion . It
performs the following steps when called:
Perform ? RequireInternalSlot (generator ,
[[AsyncGeneratorContext]] ).
Perform ? RequireInternalSlot (generator ,
[[AsyncGeneratorState]] ).
Perform ? RequireInternalSlot (generator ,
[[AsyncGeneratorQueue]] ).
If generator .[[GeneratorBrand]] is not
generatorBrand , throw a TypeError exception.
Return unused .
27.6.3.4 AsyncGeneratorEnqueue ( generator ,
completion , promiseCapability )
The abstract operation AsyncGeneratorEnqueue takes arguments generator (an
AsyncGenerator), completion (a Completion Record ),
and promiseCapability (a PromiseCapability
Record ) and returns unused . It performs the
following steps when called:
Let request be AsyncGeneratorRequest
{ [[Completion]] : completion , [[Capability]] : promiseCapability }.
Append request to generator .[[AsyncGeneratorQueue]] .
Return unused .
27.6.3.5 AsyncGeneratorCompleteStep ( generator ,
completion , done [ , realm ] )
The abstract operation AsyncGeneratorCompleteStep takes arguments generator (an
AsyncGenerator), completion (a Completion Record ),
and done (a Boolean) and optional argument realm (a Realm
Record ) and returns unused . It performs the
following steps when called:
Assert :
generator .[[AsyncGeneratorQueue]] is not empty.
Let next be the first element of generator .[[AsyncGeneratorQueue]] .
Remove the first element from generator .[[AsyncGeneratorQueue]] .
Let promiseCapability be next .[[Capability]] .
Let value be completion .[[Value]] .
If completion is a throw
completion , then
Perform ! Call (promiseCapability .[[Reject]] , undefined , «
value »).
Else,
Assert : completion is a
normal
completion .
If realm is present, then
Let oldRealm be the running execution
context 's Realm .
Set the running
execution context 's Realm to
realm .
Let iteratorResult be CreateIteratorResultObject (value ,
done ).
Set the running
execution context 's Realm to
oldRealm .
Else,
Let iteratorResult be CreateIteratorResultObject (value ,
done ).
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
iteratorResult »).
Return unused .
27.6.3.6 AsyncGeneratorResume ( generator ,
completion )
The abstract operation AsyncGeneratorResume takes arguments generator (an
AsyncGenerator) and completion (a Completion Record )
and returns unused . It performs the following steps when called:
Assert :
generator .[[AsyncGeneratorState]] is either
suspended-start or suspended-yield .
Let genContext be generator .[[AsyncGeneratorContext]] .
Let callerContext be the running execution
context .
Suspend callerContext .
Set generator .[[AsyncGeneratorState]] to
executing .
Push genContext onto the execution context
stack ; genContext is now the running execution context .
Resume the suspended evaluation of
genContext using completion as the result of the
operation that suspended it. Let result be the Completion
Record returned by the resumed computation.
Assert :
result is never an abrupt
completion .
Assert :
When we return here, genContext has already been removed from the
execution context stack and
callerContext is the currently running execution context .
Return unused .
27.6.3.7 AsyncGeneratorUnwrapYieldResumption (
resumptionValue )
The abstract operation AsyncGeneratorUnwrapYieldResumption takes argument
resumptionValue (a Completion
Record ) and returns either a normal completion
containing an ECMAScript language
value or an abrupt completion .
It performs the following steps when called:
If resumptionValue is not a return
completion , return ? resumptionValue .
Let awaited be Completion (Await (resumptionValue .[[Value]] )).
If awaited is a throw
completion , return ? awaited .
Assert :
awaited is a normal
completion .
Return ReturnCompletion (awaited .[[Value]] ).
27.6.3.8 AsyncGeneratorYield ( value )
The abstract operation AsyncGeneratorYield takes argument value (an ECMAScript language value ) and
returns either a normal completion
containing an ECMAScript language
value or an abrupt completion .
It performs the following steps when called:
Let genContext be the running execution
context .
Assert :
genContext is the execution
context of a generator.
Let generator be the value of the Generator component of
genContext .
Assert :
GetGeneratorKind () is
async .
Let completion be NormalCompletion (value ).
Assert :
The execution context stack has
at least two elements.
Let previousContext be the second to top element of the execution context stack .
Let previousRealm be previousContext 's Realm .
Perform AsyncGeneratorCompleteStep (generator ,
completion , false , previousRealm ).
Let queue be generator .[[AsyncGeneratorQueue]] .
If queue is not empty, then
NOTE: Execution continues without suspending the generator.
Let toYield be the first element of queue .
Let resumptionValue be Completion (toYield .[[Completion]] ).
Return ? AsyncGeneratorUnwrapYieldResumption (resumptionValue ).
Else,
Set generator .[[AsyncGeneratorState]] to
suspended-yield .
Remove genContext from the execution context
stack and restore the execution context that
is at the top of the execution context
stack as the running execution
context .
Let callerContext be the running execution
context .
Resume callerContext passing undefined . If
genContext is ever resumed again, let resumptionValue
be the Completion
Record with which it is resumed.
Assert : If control reaches here, then
genContext is the running execution
context again.
Return ? AsyncGeneratorUnwrapYieldResumption (resumptionValue ).
27.6.3.9 AsyncGeneratorAwaitReturn ( generator )
The abstract operation AsyncGeneratorAwaitReturn takes argument generator (an
AsyncGenerator) and returns unused . It performs the following steps
when called:
Assert :
generator .[[AsyncGeneratorState]] is
draining-queue .
Let queue be generator .[[AsyncGeneratorQueue]] .
Assert :
queue is not empty.
Let next be the first element of queue .
Let completion be Completion (next .[[Completion]] ).
Assert :
completion is a return
completion .
Let promiseCompletion be Completion (PromiseResolve (%Promise% ,
completion .[[Value]] )).
If promiseCompletion is an abrupt
completion , then
Perform AsyncGeneratorCompleteStep (generator ,
promiseCompletion , true ).
Perform AsyncGeneratorDrainQueue (generator ).
Return unused .
Assert :
promiseCompletion is a normal
completion .
Let promise be promiseCompletion .[[Value]] .
Let fulfilledClosure be a new Abstract Closure
with parameters (value ) that captures generator and performs
the following steps when called:
Assert : generator .[[AsyncGeneratorState]] is
draining-queue .
Let result be NormalCompletion (value ).
Perform AsyncGeneratorCompleteStep (generator ,
result , true ).
Perform AsyncGeneratorDrainQueue (generator ).
Return undefined .
Let onFulfilled be CreateBuiltinFunction (fulfilledClosure ,
1, "" , « »).
Let rejectedClosure be a new Abstract Closure
with parameters (reason ) that captures generator and performs
the following steps when called:
Assert : generator .[[AsyncGeneratorState]] is
draining-queue .
Let result be ThrowCompletion (reason ).
Perform AsyncGeneratorCompleteStep (generator ,
result , true ).
Perform AsyncGeneratorDrainQueue (generator ).
Return undefined .
Let onRejected be CreateBuiltinFunction (rejectedClosure ,
1, "" , « »).
Perform PerformPromiseThen (promise ,
onFulfilled , onRejected ).
Return unused .
27.6.3.10 AsyncGeneratorDrainQueue ( generator )
The abstract operation AsyncGeneratorDrainQueue takes argument generator (an
AsyncGenerator) and returns unused . It drains the generator's
AsyncGeneratorQueue until it encounters an AsyncGeneratorRequest which
holds a return completion .
It performs the following steps when called:
Assert :
generator .[[AsyncGeneratorState]] is
draining-queue .
Let queue be generator .[[AsyncGeneratorQueue]] .
Repeat, while queue is not empty,
Let next be the first element of queue .
Let completion be Completion (next .[[Completion]] ).
If completion is a return
completion , then
Perform AsyncGeneratorAwaitReturn (generator ).
Return unused .
Else,
If completion is a normal
completion , then
Set completion to NormalCompletion (undefined ).
Perform AsyncGeneratorCompleteStep (generator ,
completion , true ).
Set generator .[[AsyncGeneratorState]] to
completed .
Return unused .
27.6.3.11 CreateAsyncIteratorFromClosure ( closure ,
generatorBrand , generatorPrototype )
The abstract operation CreateAsyncIteratorFromClosure takes arguments closure (an
Abstract Closure with no parameters),
generatorBrand (a String or empty ), and
generatorPrototype (an Object) and returns an AsyncGenerator. It performs the
following steps when called:
NOTE: closure can contain uses of the Await operation and uses of the
Yield
operation to yield an IteratorResult
object .
Let internalSlotsList be « [[AsyncGeneratorState]] , [[AsyncGeneratorContext]] , [[AsyncGeneratorQueue]] , [[GeneratorBrand]] ».
Let generator be OrdinaryObjectCreate (generatorPrototype ,
internalSlotsList ).
Set generator .[[GeneratorBrand]] to
generatorBrand .
Set generator .[[AsyncGeneratorState]] to
suspended-start .
Let callerContext be the running execution
context .
Let calleeContext be a new execution
context .
Set the Function of calleeContext to null .
Set the Realm of calleeContext to the current Realm
Record .
Set the ScriptOrModule of calleeContext to callerContext 's
ScriptOrModule.
If callerContext is not already suspended, suspend
callerContext .
Push calleeContext onto the execution context
stack ; calleeContext is now the running execution context .
Perform AsyncGeneratorStart (generator ,
closure ).
Remove calleeContext from the execution context
stack and restore callerContext as the running execution context .
Return generator .
27.7 AsyncFunction Objects
AsyncFunctions are functions that are usually created by evaluating AsyncFunctionDeclaration s, AsyncFunctionExpression s,
AsyncMethod s, and AsyncArrowFunction s. They may
also be created by calling the %AsyncFunction% intrinsic.
27.7.1 The AsyncFunction Constructor
The AsyncFunction constructor :
is %AsyncFunction% .
is a subclass of Function.
creates and initializes a new AsyncFunction when called as a function rather than as a
constructor . Thus the function call
AsyncFunction(…) is equivalent to the object creation expression
new AsyncFunction(…) with the same arguments.
may be used as the value of an extends clause of a class definition. Subclass
constructors that intend to inherit the specified
AsyncFunction behaviour must include a super call to the AsyncFunction
constructor to create and initialize a subclass
instance with the internal slots necessary for built-in async function behaviour. All
ECMAScript syntactic forms for defining async function objects create direct
instances of AsyncFunction. There is no syntactic means to create instances of AsyncFunction
subclasses.
27.7.1.1 AsyncFunction ( ...parameterArgs ,
bodyArg )
The last argument (if any) specifies the body (executable code) of an async function. Any
preceding arguments specify formal parameters.
This function performs the following steps when called:
Let C be the active function object .
If bodyArg is not present, set bodyArg to the empty String.
Return ? CreateDynamicFunction (C ,
NewTarget, async , parameterArgs ,
bodyArg ).
Note
27.7.2 Properties of the AsyncFunction Constructor
The AsyncFunction constructor :
is a standard built-in function object that inherits from the
Function constructor .
has a [[Prototype]] internal slot whose value is %Function% .
has a "length"
property whose value is 1 𝔽 .
has a "name" property whose value is "AsyncFunction" .
has the following properties:
27.7.2.1 AsyncFunction.prototype
The initial value of AsyncFunction.prototype is the AsyncFunction prototype
object .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
27.7.3 Properties of the AsyncFunction Prototype Object
The AsyncFunction prototype object :
27.7.3.1 AsyncFunction.prototype.constructor
The initial value of AsyncFunction.prototype.constructor is %AsyncFunction% .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.7.3.2 AsyncFunction.prototype [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "AsyncFunction" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
27.7.4 AsyncFunction Instances
Every AsyncFunction instance is an ECMAScript function object and has the
internal slots listed in Table
30 . The value of the [[IsClassConstructor]]
internal slot for all such instances is false . AsyncFunction instances are
not constructors and do not have a [[Construct]] internal method. AsyncFunction instances do not have a
prototype property as they are not constructable.
Each AsyncFunction instance has the following own properties:
27.7.4.1 length
The specification for the "length" property of Function instances given in
20.2.4.1 also applies to
AsyncFunction instances.
27.7.4.2 name
The specification for the "name" property of Function instances given in
20.2.4.2 also applies to
AsyncFunction instances.
27.7.5 Async Functions Abstract Operations
27.7.5.1 AsyncFunctionStart ( promiseCapability ,
asyncFunctionBody )
The abstract operation AsyncFunctionStart takes arguments promiseCapability (a
PromiseCapability Record ) and
asyncFunctionBody (a FunctionBody Parse
Node , an ExpressionBody Parse
Node , or an Abstract Closure with no parameters) and
returns unused . It performs the following steps when called:
Let runningContext be the running execution
context .
Let asyncContext be a copy of runningContext .
NOTE: Copying the execution state is required for AsyncBlockStart to
resume its execution. It is ill-defined to resume a currently executing context.
Perform AsyncBlockStart (promiseCapability ,
asyncFunctionBody , asyncContext ).
Return unused .
27.7.5.2 AsyncBlockStart ( promiseCapability ,
asyncBody , asyncContext )
The abstract operation AsyncBlockStart takes arguments promiseCapability (a
PromiseCapability Record ),
asyncBody (a Parse Node or an Abstract
Closure with no parameters), and asyncContext (an
execution context ) and returns
unused . It performs the following steps when called:
Let runningContext be the running execution
context .
Let closure be a new Abstract Closure
with no parameters that captures promiseCapability and
asyncBody and performs the following steps when called:
Let acAsyncContext be the running execution
context .
If asyncBody is a Parse
Node , then
Let result be Completion (Evaluation of
asyncBody ).
Else,
Assert : asyncBody
is an Abstract Closure
with no parameters.
Let result be Completion (asyncBody ()).
Assert : If we return here, the async
function either threw an exception or performed an implicit or explicit
return; all awaiting is done.
Remove acAsyncContext from the execution context
stack and restore the execution context that
is at the top of the execution context
stack as the running execution
context .
If result is a normal
completion , then
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
undefined »).
Else if result is a return
completion , then
Perform ! Call (promiseCapability .[[Resolve]] , undefined , «
result .[[Value]] »).
Else,
Assert : result is a
throw
completion .
Perform ! Call (promiseCapability .[[Reject]] , undefined , «
result .[[Value]] »).
Return
unused .
Set the code evaluation state of asyncContext such that when evaluation
is resumed for that execution context ,
closure will be called with no arguments.
Push asyncContext onto the execution context
stack ; asyncContext is now the running execution context .
Resume the suspended evaluation of
asyncContext . Let result be the value returned by
the resumed computation.
Assert :
When we return here, asyncContext has already been removed from the
execution context stack and
runningContext is the currently running execution context .
Assert :
result is a normal
completion with a value of unused . The
possible sources of this value are Await or, if the async function doesn't await
anything, step 2.i above.
Return unused .
27.7.5.3 Await ( value )
The abstract operation Await takes argument value (an ECMAScript language value ) and
returns either a normal completion
containing either an ECMAScript language
value or empty , or a throw completion . It
performs the following steps when called:
Let asyncContext be the running execution
context .
Let promise be ? PromiseResolve (%Promise% , value ).
Let fulfilledClosure be a new Abstract Closure
with parameters (v ) that captures asyncContext and performs
the following steps when called:
Let prevContext be the running execution
context .
Suspend prevContext .
Push asyncContext onto the execution context
stack ; asyncContext is now the running execution
context .
Resume the suspended evaluation of
asyncContext using NormalCompletion (v )
as the result of the operation that suspended it.
Assert : When we reach this step,
asyncContext has already been removed from the execution context
stack and prevContext is the currently
running execution
context .
Return undefined .
Let onFulfilled be CreateBuiltinFunction (fulfilledClosure ,
1, "" , « »).
Let rejectedClosure be a new Abstract Closure
with parameters (reason ) that captures asyncContext and
performs the following steps when called:
Let prevContext be the running execution
context .
Suspend prevContext .
Push asyncContext onto the execution context
stack ; asyncContext is now the running execution
context .
Resume the suspended evaluation of
asyncContext using ThrowCompletion (reason )
as the result of the operation that suspended it.
Assert : When we reach this step,
asyncContext has already been removed from the execution context
stack and prevContext is the currently
running execution
context .
Return undefined .
Let onRejected be CreateBuiltinFunction (rejectedClosure ,
1, "" , « »).
Perform PerformPromiseThen (promise ,
onFulfilled , onRejected ).
Remove asyncContext from the execution context
stack and restore the execution context that is at
the top of the execution context stack as
the running execution context .
Let callerContext be the running execution
context .
Resume callerContext passing empty . If
asyncContext is ever resumed again, let completion be the
Completion
Record with which it is resumed.
Assert : If
control reaches here, then asyncContext is the running execution context
again.
Return completion .
28 Reflection
28.1 The Reflect Object
The Reflect object:
is %Reflect% .
is the initial value of the "Reflect" property of the global
object .
is an ordinary
object .
has a [[Prototype]] internal slot whose value is %Object.prototype% .
is not a function
object .
does not have a [[Construct]] internal method; it cannot be used as a
constructor
with the new operator.
does not have a [[Call]] internal method; it cannot be invoked as a
function.
28.1.1 Reflect.apply ( target , thisArgument ,
argumentsList )
This function performs the following steps when called:
If IsCallable (target ) is
false , throw a TypeError exception.
Let args be ? CreateListFromArrayLike (argumentsList ).
Perform PrepareForTailCall ().
Return ? Call (target ,
thisArgument , args ).
28.1.2 Reflect.construct ( target ,
argumentsList [ , newTarget ] )
This function performs the following steps when called:
If IsConstructor (target ) is
false , throw a TypeError exception.
If newTarget is not present, set newTarget to target .
Else if IsConstructor (newTarget ) is
false , throw a TypeError exception.
Let args be ? CreateListFromArrayLike (argumentsList ).
Return ? Construct (target , args ,
newTarget ).
28.1.3 Reflect.defineProperty ( target ,
propertyKey , attributes )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let key be ? ToPropertyKey (propertyKey ).
Let desc be ? ToPropertyDescriptor (attributes ).
Return ? target .[[DefineOwnProperty]] (key ,
desc ).
28.1.4 Reflect.deleteProperty ( target ,
propertyKey )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let key be ? ToPropertyKey (propertyKey ).
Return ? target .[[Delete]] (key ).
28.1.5 Reflect.get ( target , propertyKey [ ,
receiver ] )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let key be ? ToPropertyKey (propertyKey ).
If receiver is not present, then
Set receiver to target .
Return ? target .[[Get]] (key , receiver ).
28.1.6 Reflect.getOwnPropertyDescriptor ( target ,
propertyKey )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let key be ? ToPropertyKey (propertyKey ).
Let desc be ? target .[[GetOwnProperty]] (key ).
Return FromPropertyDescriptor (desc ).
28.1.7 Reflect.getPrototypeOf ( target )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Return ? target .[[GetPrototypeOf]] () .
28.1.8 Reflect.has ( target , propertyKey )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let key be ? ToPropertyKey (propertyKey ).
Return ? target .[[HasProperty]] (key ).
28.1.9 Reflect.isExtensible ( target )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Return ? target .[[IsExtensible]] () .
28.1.10 Reflect.ownKeys ( target )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let keys be ? target .[[OwnPropertyKeys]] () .
Return CreateArrayFromList (keys ).
28.1.11 Reflect.preventExtensions ( target )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Return ? target .[[PreventExtensions]] () .
28.1.12 Reflect.set ( target , propertyKey ,
V [ , receiver ] )
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
Let key be ? ToPropertyKey (propertyKey ).
If receiver is not present, then
Set receiver to target .
Return ? target .[[Set]] (key , V ,
receiver ).
28.1.13 Reflect.setPrototypeOf ( target , proto
)
This function performs the following steps when called:
If target is not an Object , throw a
TypeError exception.
If proto is not an Object and proto is
not null , throw a TypeError exception.
Return ? target .[[SetPrototypeOf]] (proto ).
28.1.14 Reflect [ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the
String value "Reflect" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : true }.
28.2 Proxy Objects
28.2.1 The Proxy Constructor
The Proxy constructor :
is %Proxy% .
is the initial value of the "Proxy" property of the global
object .
creates and initializes a new Proxy object when called as a constructor .
is not intended to be called as a function and will throw an exception when called in that
manner.
28.2.1.1 Proxy ( target , handler )
This function performs the following steps when called:
If NewTarget is undefined , throw a TypeError
exception.
Return ? ProxyCreate (target ,
handler ).
28.2.2 Properties of the Proxy Constructor
The Proxy constructor :
has a [[Prototype]] internal slot whose value is %Function.prototype% .
does not have a "prototype" property because Proxy objects do not have a
[[Prototype]] internal slot that requires initialization.
has the following properties:
28.2.2.1 Proxy.revocable ( target , handler
)
This function creates a revocable Proxy object.
It performs the following steps when called:
Let proxy be ? ProxyCreate (target ,
handler ).
Let revokerClosure be a new Abstract Closure
with no parameters that captures nothing and performs the following steps when
called:
Let F be the active function
object .
Let p be F .[[RevocableProxy]] .
If p is null , return
undefined .
Set F .[[RevocableProxy]] to
null .
Assert : p is a Proxy exotic object .
Set p .[[ProxyTarget]] to
null .
Set p .[[ProxyHandler]] to
null .
Return undefined .
Let revoker be CreateBuiltinFunction (revokerClosure ,
0, "" , « [[RevocableProxy]] »).
Set revoker .[[RevocableProxy]] to
proxy .
Let result be OrdinaryObjectCreate (%Object.prototype% ).
Perform ! CreateDataPropertyOrThrow (result ,
"proxy" , proxy ).
Perform ! CreateDataPropertyOrThrow (result ,
"revoke" , revoker ).
Return result .
28.3 Module Namespace Objects
A Module Namespace Object is a module namespace exotic object that
provides runtime property-based access to a module's exported bindings. There is no constructor function
for Module Namespace Objects. Instead, such an object is created for each module that is imported by
an ImportDeclaration that
contains a NameSpaceImport .
In addition to the properties specified in 10.4.6 each Module
Namespace Object has the following own property:
28.3.1 %Symbol.toStringTag%
The initial value of the %Symbol.toStringTag% property is the
String value "Module" .
This property has the attributes { [[Writable]] :
false , [[Enumerable]] : false ,
[[Configurable]] : false }.
29 Memory Model
The memory consistency model, or memory model , specifies the possible orderings
of Shared Data Block events , arising via
accessing TypedArray
instances backed by a SharedArrayBuffer and via methods on the Atomics object. When the program has no
data races (defined below), the ordering of events appears as sequentially consistent, i.e., as an
interleaving of actions from each agent . When the program has data races, shared memory operations
may appear sequentially inconsistent. For example, programs may exhibit causality-violating behaviour
and other astonishments. These astonishments arise from compiler transforms and the design of CPUs
(e.g., out-of-order execution and speculation). The memory model defines both the precise conditions
under which a program exhibits sequentially consistent behaviour as well as the possible values read
from data races. To wit, there is no undefined behaviour.
The memory model is defined as relational constraints on events introduced by abstract operations on
SharedArrayBuffer or by methods on the Atomics object during an evaluation.
Note
This section provides an axiomatic model on events introduced by the abstract operations
on SharedArrayBuffers. It bears stressing that the model is not expressible algorithmically,
unlike the rest of this specification. The nondeterministic introduction of events by abstract operations
is the interface between the operational semantics of ECMAScript evaluation and the axiomatic
semantics of the memory model. The semantics of these events is defined by considering graphs of
all events in an evaluation. These are neither Static Semantics nor Runtime Semantics. There is
no demonstrated algorithmic implementation, but instead a set of constraints that determine if a
particular event graph is allowed or disallowed.
29.1 Memory Model Fundamentals
Shared memory accesses (reads and writes) are divided into two groups, atomic accesses and data
accesses, defined below. Atomic accesses are sequentially consistent, i.e., there is a strict total
ordering of events agreed upon by all agents in an agent cluster . Non-atomic accesses
do not have a strict total ordering agreed upon by all agents , i.e., unordered.
Note 1
No orderings weaker than sequentially consistent and stronger than unordered, such as
release-acquire, are supported.
A Shared Data Block event is either a
ReadSharedMemory , WriteSharedMemory , or ReadModifyWriteSharedMemory Record .
Table 96: ReadSharedMemory Event Fields
Field Name
Value
Meaning
[[Order]]
seq-cst or unordered
The weakest ordering guaranteed by the memory model for
the event.
[[NoTear]]
a Boolean
Whether this event is allowed to read from multiple write events with equal
range as this event.
[[Block]]
a Shared Data Block
The block the event operates on.
[[ByteIndex]]
a non-negative integer
The byte address of the read in [[Block]] .
[[ElementSize]]
a non-negative integer
The size of the read.
Table 97: WriteSharedMemory Event Fields
Field Name
Value
Meaning
[[Order]]
seq-cst , unordered , or
init
The weakest ordering guaranteed by the memory model for
the event.
[[NoTear]]
a Boolean
Whether this event is allowed to be read from multiple read events with equal
range as this event.
[[Block]]
a Shared Data Block
The block the event operates on.
[[ByteIndex]]
a non-negative integer
The byte address of the write in [[Block]] .
[[ElementSize]]
a non-negative integer
The size of the write.
[[Payload]]
a List of
byte values
The List of
byte values to be read by other
events.
Table 98: ReadModifyWriteSharedMemory
Event Fields
These events are introduced by abstract
operations or by methods on the Atomics object.
Some operations may also introduce Synchronize events. A Synchronize event has no fields, and exists
purely to directly constrain the permitted orderings of other events.
In addition to Shared
Data Block and Synchronize events, there are host -specific events.
Let the range of a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory event be the
Set of contiguous integers from its [[ByteIndex]] to
[[ByteIndex]] + [[ElementSize]] - 1. Two events'
ranges are equal when the events have the same [[Block]] , and the ranges
are element-wise equal. Two events' ranges are overlapping when the events have the same [[Block]] , the ranges are not equal and their intersection is non-empty. Two
events' ranges are disjoint when the events do not have the same [[Block]]
or their ranges are neither equal nor overlapping.
Note 2
Examples of host -specific synchronizing events that should be
accounted for are: sending a SharedArrayBuffer from one agent to another (e.g., by
postMessage in a browser), starting and stopping agents , and communicating within the
agent
cluster via channels other than shared memory. For a particular
execution execution , those events are provided by the host via the host-synchronizes-with strict partial order .
Additionally, hosts
can add host -specific
synchronizing events to execution .[[EventList]] so as to
participate in the is-agent-order-before Relation .
Events are ordered within candidate executions by the relations
defined below.
29.2 Agent Events Records
An Agent Events Record is a Record with the following
fields.
Table 99: Agent Events Record Fields
Field Name
Value
Meaning
[[AgentSignifier]]
an agent
signifier
The agent whose evaluation resulted in this
ordering.
[[EventList]]
a List of
events
Events are appended to the list during evaluation.
[[AgentSynchronizesWith]]
a List of
pairs of Synchronize events
Synchronize
relationships introduced by the operational semantics.
29.3 Chosen Value Records
A Chosen Value Record is a Record with the following
fields.
Table 100: Chosen Value Record Fields
29.4 Candidate Executions
A candidate execution of the evaluation of
an agent
cluster is a Record with the
following fields.
Table 101: Candidate Execution Record Fields
An empty candidate execution is a
candidate execution Record whose fields are empty
Lists .
29.5 Abstract Operations for the Memory Model
29.5.1 EventSet ( execution )
The abstract operation EventSet takes argument execution (a candidate execution ) and returns a Set
of events. It performs the following steps when called:
Let events be an empty Set.
For each Agent Events Record
aer of execution .[[EventsRecords]] , do
For each event E of aer .[[EventList]] , do
Add E to events .
Return events .
29.5.2 SharedDataBlockEventSet ( execution )
The abstract operation SharedDataBlockEventSet takes argument execution (a candidate execution ) and returns a Set
of events. It performs the following steps when called:
Let events be an empty Set.
For each event E of EventSet (execution ), do
If E is a ReadSharedMemory ,
WriteSharedMemory ,
or ReadModifyWriteSharedMemory
event, add E to events .
Return events .
29.5.3 HostEventSet ( execution )
The abstract operation HostEventSet takes argument execution (a candidate execution ) and returns a Set
of events. It performs the following steps when called:
Let events be an empty Set.
For each event E of EventSet (execution ), do
If E is not in SharedDataBlockEventSet (execution ),
add E to events .
Return events .
29.5.4 ComposeWriteEventBytes ( execution ,
byteIndex , Ws )
The abstract operation ComposeWriteEventBytes takes arguments execution (a candidate execution ),
byteIndex (a non-negative integer ), and Ws (a List of either WriteSharedMemory or ReadModifyWriteSharedMemory events)
and returns a List of byte
values . It performs the following steps when called:
Let byteLocation be byteIndex .
Let bytesRead be a new empty List .
For each element W of Ws , do
Assert : W has
byteLocation in its range.
Let payloadIndex be byteLocation - W .[[ByteIndex]] .
If W is a WriteSharedMemory
event, then
Let byte be W .[[Payload]] [payloadIndex ].
Else,
Assert : W is a
ReadModifyWriteSharedMemory
event.
Let bytes be ValueOfReadEvent (execution ,
W ).
Let bytesModified be W .[[ModifyOp]] (bytes , W .[[Payload]] ).
Let byte be
bytesModified [payloadIndex ].
Append byte to bytesRead .
Set byteLocation to byteLocation + 1.
Return bytesRead .
Note 1
The read-modify-write modification [[ModifyOp]] is given by the
function properties on the Atomics object that introduce ReadModifyWriteSharedMemory
events.
Note 2
This abstract operation composes a List of write
events into a List of byte
values . It is used in the event semantics of ReadSharedMemory and
ReadModifyWriteSharedMemory
events.
29.5.5 ValueOfReadEvent ( execution , R )
The abstract operation ValueOfReadEvent takes arguments execution (a candidate execution ) and R (a
ReadSharedMemory or ReadModifyWriteSharedMemory event)
and returns a List of byte
values . It performs the following steps when called:
Let Ws be reads-bytes-from (R ) in
execution .
Assert :
Ws is a List of WriteSharedMemory or
ReadModifyWriteSharedMemory
events with length equal to R .[[ElementSize]] .
Return ComposeWriteEventBytes (execution ,
R .[[ByteIndex]] , Ws ).
29.6 Relations of Candidate Executions
The following relations and mathematical functions are parameterized over a particular candidate
execution and order its events.
29.6.1 is-agent-order-before
For a candidate execution
execution , its is-agent-order-before Relation is the least
Relation on events that satisfies the following.
For events E and D , E is-agent-order-before D in
execution if there is some Agent Events Record
aer in execution .[[EventsRecords]] such that
aer .[[EventList]] contains both E and
D and E is before D in List order of
aer .[[EventList]] .
Note
Each agent
introduces events in a per-agent strict total
order during the evaluation. This is the union of those strict total
orders .
29.6.2 reads-bytes-from
For a candidate execution
execution , its reads-bytes-from function is a mathematical function mapping
events in SharedDataBlockEventSet (execution )
to Lists of events in
SharedDataBlockEventSet (execution )
that satisfies the following conditions.
A candidate execution always admits a
reads-bytes-from function.
29.6.3 reads-from
For a candidate execution
execution , its reads-from Relation is the least
Relation on events that satisfies the following.
29.6.4 host-synchronizes-with
For a candidate execution
execution , its host-synchronizes-with Relation is a host -provided strict partial order on
host -specific events that
satisfies at least the following.
If E host-synchronizes-with D in execution , HostEventSet (execution ) contains
E and D .
There is no cycle in the union of host-synchronizes-with and is-agent-order-before in
execution .
Note 1
For two host -specific events E and D
in a candidate execution
execution , E host-synchronizes-with D in
execution implies E happens-before
D in execution .
Note 2
This Relation allows
the host to
provide additional synchronization mechanisms, such as postMessage between
HTML workers.
29.6.5 synchronizes-with
For a candidate execution
execution , its synchronizes-with Relation is the least
Relation on events that satisfies the following.
For events R and W , W synchronizes-with R in
execution if R reads-from W in
execution , R .[[Order]] is
seq-cst , W .[[Order]] is
seq-cst , and R and W have equal ranges.
For each element eventsRecord of execution .[[EventsRecords]] , the following is true.
For events S and Sw , S synchronizes-with
Sw in execution if eventsRecord .[[AgentSynchronizesWith]] contains (S ,
Sw ).
For events E and D , E synchronizes-with D in
execution if execution .[[HostSynchronizesWith]] contains (E , D ).
Note 1
Owing to convention in memory model literature, in a candidate execution
execution , write events synchronizes-with read events, instead of read events
synchronizes-with write events.
Note 2
In a candidate execution
execution , init events do not participate in this
Relation and are
instead constrained directly by happens-before .
Note 3
In a candidate execution
execution , not all seq-cst events related by reads-from are related by
synchronizes-with. Only events that also have equal ranges are related by
synchronizes-with.
Note 4
For Shared Data Block events
R and W in a candidate
execution execution such that W
synchronizes-with R , R may reads-from other writes
than W .
29.6.6 happens-before
For a candidate execution
execution , its happens-before Relation is the least
Relation on events that satisfies the following.
Note
Because happens-before is a superset of agent -order, a candidate execution is
consistent with the single-thread evaluation semantics of ECMAScript.
29.7 Properties of Valid Executions
29.7.1 Valid Chosen Reads
A candidate execution execution
has valid chosen reads if the following algorithm returns true .
For each ReadSharedMemory or
ReadModifyWriteSharedMemory
event R of SharedDataBlockEventSet (execution ),
do
Let chosenValueRecord be the element of execution .[[ChosenValues]] whose [[Event]] field is R .
Let chosenValue be chosenValueRecord .[[ChosenValue]] .
Let readValue be ValueOfReadEvent (execution ,
R ).
Let chosenLen be the number of elements in chosenValue .
Let readLen be the number of elements in readValue .
If chosenLen ≠ readLen , then
Return false .
If chosenValue [i ] ≠ readValue [i ] for
some integer i in the interval
from 0 (inclusive) to chosenLen (exclusive), then
Return false .
Return true .
29.7.2 Coherent Reads
A candidate execution execution
has coherent reads if the following algorithm returns true .
For each ReadSharedMemory or
ReadModifyWriteSharedMemory
event R of SharedDataBlockEventSet (execution ),
do
Let Ws be reads-bytes-from (R )
in execution .
Let byteLocation be R .[[ByteIndex]] .
For each element W of Ws , do
If R happens-before
W in execution , then
Return false .
If there exists a WriteSharedMemory
or ReadModifyWriteSharedMemory
event V that has byteLocation in its range such
that W happens-before
V in execution and V happens-before
R in execution , then
Return false .
Set byteLocation to byteLocation + 1.
Return true .
29.7.3 Tear Free Reads
A candidate execution execution
has tear free reads if the following algorithm returns true .
For each ReadSharedMemory or
ReadModifyWriteSharedMemory
event R of SharedDataBlockEventSet (execution ),
do
If R .[[NoTear]] is true ,
then
Assert : The remainder of dividing
R .[[ByteIndex]] by R .[[ElementSize]] is 0.
For each event W such that R reads-from W in
execution and W .[[NoTear]] is true , do
If R and W have equal ranges and there
exists an event V such that V and
W have equal ranges, V .[[NoTear]] is true ,
W and V are not the same Shared Data Block
event , and R reads-from
V in execution , then
Return false .
Return true .
Note
An event's [[NoTear]] field is true when that
event was introduced via accessing an integer TypedArray , and
false when introduced via accessing a floating point TypedArray
or DataView.
Intuitively, this requirement says when a memory range is accessed in an aligned fashion
via an integer TypedArray , a single write
event on that range must "win" when in a data race with other write
events with equal ranges. More precisely, this requirement says an aligned read event
cannot read a value composed of bytes from multiple, different write events all with
equal ranges. It is possible, however, for an aligned read event to read from multiple
write events with overlapping ranges.
29.7.4 Sequentially Consistent Atomics
For a candidate execution
execution , is-memory-order-before is a strict total order of all
events in EventSet (execution ) that satisfies the
following.
A candidate execution has sequentially
consistent atomics if it admits an is-memory-order-before Relation .
Note 3
While is-memory-order-before includes all events in EventSet (execution ), those that
are not constrained by happens-before or synchronizes-with in
execution are allowed to occur anywhere in the order.
29.7.5 Valid Executions
A candidate execution execution
is a valid execution (or simply an execution) if all of the following are true.
All programs have at least one valid execution.
29.8 Races
For an execution execution and events E and D that are contained in
SharedDataBlockEventSet (execution ),
E and D are in a race if the following algorithm returns
true .
If E and D are not the same Shared Data Block event , then
If it is not the case that both E happens-before
D in execution and D happens-before E in
execution , then
If E and D are both WriteSharedMemory
or ReadModifyWriteSharedMemory
events and E and D do not have disjoint ranges, then
Return true .
If E reads-from D in
execution or D reads-from
E in execution , then
Return true .
Return false .
29.9 Data Races
For an execution execution and events E and D that are contained in
SharedDataBlockEventSet (execution ),
E and D are in a data race if the following algorithm
returns true .
If E and D are in a race in execution , then
If E .[[Order]] is not
seq-cst or D .[[Order]] is
not seq-cst , then
Return true .
If E and D have overlapping ranges, then
Return true .
Return false .
29.10 Data Race Freedom
An execution execution is data race free if there are no two
events in SharedDataBlockEventSet (execution )
that are in a data
race .
A program is data race free if all its executions are data race free.
The memory
model guarantees sequential consistency of all events for data race free
programs.
29.11 Shared Memory Guidelines
Note 1
The following are guidelines for ECMAScript programmers working with shared memory.
We recommend programs be kept data race free , i.e., make it so that
it is impossible for there to be concurrent non-atomic operations on the same memory
location. Data race free programs have
interleaving semantics where each step in the evaluation semantics of each agent are interleaved with
each other. For data race free programs, it is not
necessary to understand the details of the memory model . The details are
unlikely to build intuition that will help one to better write ECMAScript.
More generally, even if a program is not data race free it may
have predictable behaviour, so long as atomic operations are not involved in any data races
and the operations that race all have the same access size. The simplest way to arrange for
atomics not to be involved in races is to ensure that different memory cells are used by
atomic and non-atomic operations and that atomic accesses of different sizes are not used to
access the same cells at the same time. Effectively, the program should treat shared memory
as strongly typed as much as possible. One still cannot depend on the ordering and timing of
non-atomic accesses that race, but if memory is treated as strongly typed the racing
accesses will not "tear" (bits of their values will not be mixed).
Note 2
The following are guidelines for ECMAScript implementers writing compiler transformations for
programs using shared memory.
It is desirable to allow most program transformations that are valid in a single-agent setting in a
multi-agent setting,
to ensure that the performance of each agent in a multi-agent program is as good as it would be
in a single-agent
setting. Frequently these transformations are hard to judge. We outline some rules about
program transformations that are intended to be taken as normative (in that they are implied
by the memory
model or stronger than what the memory model implies) but
which are likely not exhaustive. These rules are intended to apply to program
transformations that precede the introductions of the events that make up the is-agent-order-before Relation .
Let an agent-order slice be the subset
of the is-agent-order-before Relation pertaining
to a single agent .
Let possible read values of a read event be the set of all values of
ValueOfReadEvent for that event across
all valid executions.
Any transformation of an agent-order slice that is valid in the absence of shared memory is
valid in the presence of shared memory, with the following exceptions.
Atomics are carved in stone : Program transformations must not cause the
seq-cst events in an agent-order slice to be reordered with
its unordered operations, nor its
seq-cst operations to be reordered with each other, nor may a
program transformation remove a seq-cst operation from the
is-agent-order-before Relation .
(In practice, the prohibition on reorderings forces a compiler to assume that every
seq-cst operation is a synchronization and included in the
final is-memory-order-before Relation ,
which it would usually have to assume anyway in the absence of inter-agent program
analysis. It also forces the compiler to assume that every call where the callee's
effects on the memory-order are unknown may contain seq-cst
operations.)
Reads must be stable : Any given shared memory read must only observe a
single value in an execution.
(For example, if what is semantically a single read in the program is executed
multiple times then the program is subsequently allowed to observe only one of the
values read. A transformation known as rematerialization can violate this rule.)
Writes must be stable : All observable writes to shared memory must follow
from program semantics in an execution.
(For example, a transformation may not introduce certain observable writes, such as
by using read-modify-write operations on a larger location to write a smaller datum,
writing a value to memory that the program could not have written, or writing a
just-read value back to the location it was read from, if that location could have
been overwritten by another agent after the read.)
Possible read values must be non-empty : Program transformations cannot cause
the possible read values of a shared memory read to become empty.
(Counterintuitively, this rule in effect restricts transformations on writes, because
writes have force in memory model insofar as to be read
by read events. For example, writes may be moved and coalesced and sometimes
reordered between two seq-cst operations, but the
transformation may not remove every write that updates a location; some write must
be preserved.)
Examples of transformations that remain valid are: merging multiple non-atomic reads from the
same location, reordering non-atomic reads, introducing speculative non-atomic reads,
merging multiple non-atomic writes to the same location, reordering non-atomic writes to
different locations, and hoisting non-atomic reads out of loops even if that affects
termination. Note in general that aliased TypedArrays make it hard to prove that locations
are different.
Note 3
The following are guidelines for ECMAScript implementers generating machine code for shared
memory accesses.
For architectures with memory models no weaker than those of ARM or Power, non-atomic stores
and loads may be compiled to bare stores and loads on the target architecture. Atomic stores
and loads may be compiled down to instructions that guarantee sequential consistency. If no
such instructions exist, memory barriers are to be employed, such as placing barriers on
both sides of a bare store or load. Read-modify-write operations may be compiled to
read-modify-write instructions on the target architecture, such as
LOCK-prefixed instructions on x86, load-exclusive/store-exclusive instructions
on ARM, and load-link/store-conditional instructions on Power.
Specifically, the memory model is intended to allow code
generation as follows.
Every atomic operation in the program is assumed to be necessary.
Atomic operations are never rearranged with each other or with non-atomic operations.
Functions are always assumed to perform atomic operations.
Atomic operations are never implemented as read-modify-write operations on larger data,
but as non-lock-free atomics if the platform does not have atomic operations of the
appropriate size. (We already assume that every platform has normal memory access
operations of every interesting size.)
Naive code generation uses these patterns:
Regular loads and stores compile to single load and store instructions.
Lock-free atomic loads and stores compile to a full (sequentially consistent) fence, a
regular load or store, and a full fence.
Lock-free atomic read-modify-write accesses compile to a full fence, an atomic
read-modify-write instruction sequence, and a full fence.
Non-lock-free atomics compile to a spinlock acquire, a full fence, a series of
non-atomic load and store instructions, a full fence, and a spinlock release.
That mapping is correct so long as an atomic operation on an address range does not race with
a non-atomic write or with an atomic operation of different size. However, that is all we
need: the memory model effectively demotes the atomic
operations involved in a race to non-atomic status. On the other hand, the naive mapping is
quite strong: it allows atomic operations to be used as sequentially consistent fences,
which the memory model does not actually guarantee.
Local improvements to those basic patterns are also allowed, subject to the constraints of
the memory
model . For example:
There are obvious platform-dependent improvements that remove redundant fences. For
example, on x86 the fences around lock-free atomic loads and stores can always be
omitted except for the fence following a store, and no fence is needed for lock-free
read-modify-write instructions, as these all use LOCK-prefixed
instructions. On many platforms there are fences of several strengths, and weaker fences
can be used in certain contexts without destroying sequential consistency.
Most modern platforms support lock-free atomics for all the data sizes required by
ECMAScript atomics. Should non-lock-free atomics be needed, the fences surrounding the
body of the atomic operation can usually be folded into the lock and unlock steps. The
simplest solution for non-lock-free atomics is to have a single lock word per
SharedArrayBuffer.
There are also more complicated platform-dependent local improvements, requiring some
code analysis. For example, two back-to-back fences often have the same effect as a
single fence, so if code is generated for two atomic operations in sequence, only a
single fence need separate them. On x86, even a single fence separating atomic stores
can be omitted, as the fence following a store is only needed to separate the store from
a subsequent load.
Annex A (informative) Grammar Summary
A.1 Lexical Grammar
SourceCharacter ::
any Unicode code point
InputElementDiv ::
WhiteSpace
LineTerminator
Comment
CommonToken
DivPunctuator
RightBracePunctuator
InputElementRegExp ::
WhiteSpace
LineTerminator
Comment
CommonToken
RightBracePunctuator
RegularExpressionLiteral
InputElementRegExpOrTemplateTail
::
WhiteSpace
LineTerminator
Comment
CommonToken
RegularExpressionLiteral
TemplateSubstitutionTail
InputElementTemplateTail
::
WhiteSpace
LineTerminator
Comment
CommonToken
DivPunctuator
TemplateSubstitutionTail
InputElementHashbangOrRegExp
::
WhiteSpace
LineTerminator
Comment
CommonToken
HashbangComment
RegularExpressionLiteral
WhiteSpace ::
<TAB>
<VT>
<FF>
<ZWNBSP>
<USP>
LineTerminator ::
<LF>
<CR>
<LS>
<PS>
LineTerminatorSequence
::
<LF>
<CR>
[lookahead ≠ <LF> ]
<LS>
<PS>
<CR>
<LF>
Comment ::
MultiLineComment
SingleLineComment
MultiLineComment ::
/*
MultiLineCommentChars opt
*/
MultiLineCommentChars
::
MultiLineNotAsteriskChar
MultiLineCommentChars opt
*
PostAsteriskCommentChars opt
PostAsteriskCommentChars
::
MultiLineNotForwardSlashOrAsteriskChar
MultiLineCommentChars opt
*
PostAsteriskCommentChars opt
MultiLineNotAsteriskChar
::
SourceCharacter but not
*
MultiLineNotForwardSlashOrAsteriskChar
::
SourceCharacter but not one of
/ or *
SingleLineComment ::
//
SingleLineCommentChars opt
SingleLineCommentChars
::
SingleLineCommentChar
SingleLineCommentChars opt
SingleLineCommentChar
::
SourceCharacter but not
LineTerminator
HashbangComment ::
#!
SingleLineCommentChars opt
CommonToken ::
IdentifierName
PrivateIdentifier
Punctuator
NumericLiteral
StringLiteral
Template
PrivateIdentifier ::
#
IdentifierName
IdentifierName ::
IdentifierStart
IdentifierName
IdentifierPart
IdentifierStart ::
IdentifierStartChar
\
UnicodeEscapeSequence
IdentifierPart ::
IdentifierPartChar
\
UnicodeEscapeSequence
IdentifierStartChar ::
UnicodeIDStart
$
_
IdentifierPartChar ::
UnicodeIDContinue
$
AsciiLetter :: one
of a b c d
e f g h i
j k l m n
o p q r s
t u v w x
y z A B C
D E F G H
I J K L M
N O P Q R
S T U V W
X Y Z
UnicodeIDStart ::
any Unicode code point with the Unicode property “ID_Start”
UnicodeIDContinue ::
any Unicode code point with the Unicode property “ID_Continue”
ReservedWord :: one
of await break case
catch class const continue
debugger default delete do
else enum export extends
false finally for function
if import in instanceof
new null return super
switch this throw true
try typeof var void
while with yield
Punctuator ::
OptionalChainingPunctuator
OtherPunctuator
OptionalChainingPunctuator
::
?.
[lookahead ∉ DecimalDigit ]
OtherPunctuator ::
one of { ( )
[ ] . ... ;
, < > <=
>= == != === !==
+ - * % **
++ -- << >>
>>> & | ^
! ~ && || ??
? : = += -=
*= %= **= <<=
>>= >>>= &= |=
^= &&= ||= ??=
=>
DivPunctuator ::
/
/=
RightBracePunctuator ::
}
NullLiteral ::
null
BooleanLiteral ::
true
false
NumericLiteralSeparator
::
_
NumericLiteral ::
DecimalLiteral
DecimalBigIntegerLiteral
NonDecimalIntegerLiteral [+Sep]
NonDecimalIntegerLiteral [+Sep]
BigIntLiteralSuffix
LegacyOctalIntegerLiteral
DecimalBigIntegerLiteral
::
0
BigIntLiteralSuffix
NonZeroDigit
DecimalDigits [+Sep] opt
BigIntLiteralSuffix
NonZeroDigit
NumericLiteralSeparator
DecimalDigits [+Sep]
BigIntLiteralSuffix
NonDecimalIntegerLiteral [Sep]
::
BinaryIntegerLiteral [?Sep]
OctalIntegerLiteral [?Sep]
HexIntegerLiteral [?Sep]
BigIntLiteralSuffix ::
n
DecimalLiteral ::
DecimalIntegerLiteral
.
DecimalDigits [+Sep] opt
ExponentPart [+Sep] opt
.
DecimalDigits [+Sep]
ExponentPart [+Sep] opt
DecimalIntegerLiteral
ExponentPart [+Sep] opt
DecimalIntegerLiteral
::
0
NonZeroDigit
NonZeroDigit
NumericLiteralSeparator opt
DecimalDigits [+Sep]
NonOctalDecimalIntegerLiteral
DecimalDigits [Sep]
::
DecimalDigit
DecimalDigits [?Sep]
DecimalDigit
[+Sep]
DecimalDigits [+Sep]
NumericLiteralSeparator
DecimalDigit
DecimalDigit :: one
of 0 1 2 3
4 5 6 7 8
9
NonZeroDigit :: one
of 1 2 3 4
5 6 7 8 9
ExponentPart [Sep]
::
ExponentIndicator
SignedInteger [?Sep]
ExponentIndicator ::
one of e E
SignedInteger [Sep]
::
DecimalDigits [?Sep]
+
DecimalDigits [?Sep]
-
DecimalDigits [?Sep]
BinaryIntegerLiteral [Sep]
::
0b
BinaryDigits [?Sep]
0B
BinaryDigits [?Sep]
BinaryDigits [Sep]
::
BinaryDigit
BinaryDigits [?Sep]
BinaryDigit
[+Sep]
BinaryDigits [+Sep]
NumericLiteralSeparator
BinaryDigit
BinaryDigit :: one
of 0 1
OctalIntegerLiteral [Sep]
::
0o
OctalDigits [?Sep]
0O
OctalDigits [?Sep]
OctalDigits [Sep]
::
OctalDigit
OctalDigits [?Sep]
OctalDigit
[+Sep]
OctalDigits [+Sep]
NumericLiteralSeparator
OctalDigit
LegacyOctalIntegerLiteral
::
0
OctalDigit
LegacyOctalIntegerLiteral
OctalDigit
NonOctalDecimalIntegerLiteral
::
0
NonOctalDigit
LegacyOctalLikeDecimalIntegerLiteral
NonOctalDigit
NonOctalDecimalIntegerLiteral
DecimalDigit
LegacyOctalLikeDecimalIntegerLiteral
::
0
OctalDigit
LegacyOctalLikeDecimalIntegerLiteral
OctalDigit
OctalDigit :: one
of 0 1 2 3
4 5 6 7
NonOctalDigit ::
one of 8 9
HexIntegerLiteral [Sep]
::
0x
HexDigits [?Sep]
0X
HexDigits [?Sep]
HexDigits [Sep]
::
HexDigit
HexDigits [?Sep]
HexDigit
[+Sep]
HexDigits [+Sep]
NumericLiteralSeparator
HexDigit
HexDigit :: one
of 0 1 2 3
4 5 6 7 8
9 a b c d
e f A B C
D E F
StringLiteral ::
"
DoubleStringCharacters opt
"
'
SingleStringCharacters opt
'
DoubleStringCharacters
::
DoubleStringCharacter
DoubleStringCharacters opt
SingleStringCharacters
::
SingleStringCharacter
SingleStringCharacters opt
DoubleStringCharacter
::
SourceCharacter but not one of
" or \ or LineTerminator
<LS>
<PS>
\
EscapeSequence
LineContinuation
SingleStringCharacter
::
SourceCharacter but not one of
' or \ or LineTerminator
<LS>
<PS>
\
EscapeSequence
LineContinuation
LineContinuation ::
\
LineTerminatorSequence
EscapeSequence ::
CharacterEscapeSequence
0
[lookahead ∉ DecimalDigit ]
LegacyOctalEscapeSequence
NonOctalDecimalEscapeSequence
HexEscapeSequence
UnicodeEscapeSequence
CharacterEscapeSequence
::
SingleEscapeCharacter
NonEscapeCharacter
SingleEscapeCharacter
:: one of ' "
\ b f n r
t v
NonEscapeCharacter ::
SourceCharacter but not one of
EscapeCharacter or LineTerminator
EscapeCharacter ::
SingleEscapeCharacter
DecimalDigit
x
u
LegacyOctalEscapeSequence
::
0
[lookahead ∈ { 8 , 9 }]
NonZeroOctalDigit
[lookahead ∉ OctalDigit ]
ZeroToThree
OctalDigit
[lookahead ∉ OctalDigit ]
FourToSeven
OctalDigit
ZeroToThree
OctalDigit
OctalDigit
NonZeroOctalDigit ::
OctalDigit but not
0
ZeroToThree :: one
of 0 1 2
3
FourToSeven :: one
of 4 5 6
7
NonOctalDecimalEscapeSequence
:: one of 8
9
HexEscapeSequence ::
x
HexDigit
HexDigit
UnicodeEscapeSequence
::
u
Hex4Digits
u{
CodePoint
}
Hex4Digits ::
HexDigit
HexDigit
HexDigit
HexDigit
RegularExpressionLiteral
::
/
RegularExpressionBody
/
RegularExpressionFlags
RegularExpressionBody
::
RegularExpressionFirstChar
RegularExpressionChars
RegularExpressionChars
::
[empty]
RegularExpressionChars
RegularExpressionChar
RegularExpressionFirstChar
::
RegularExpressionNonTerminator
but not one of * or \ or / or
[
RegularExpressionBackslashSequence
RegularExpressionClass
RegularExpressionChar
::
RegularExpressionNonTerminator
but not one of \ or / or [
RegularExpressionBackslashSequence
RegularExpressionClass
RegularExpressionBackslashSequence
::
\
RegularExpressionNonTerminator
RegularExpressionNonTerminator
::
SourceCharacter but not
LineTerminator
RegularExpressionClass
::
[
RegularExpressionClassChars
]
RegularExpressionClassChars
::
[empty]
RegularExpressionClassChars
RegularExpressionClassChar
RegularExpressionClassChar
::
RegularExpressionNonTerminator
but not one of ] or \
RegularExpressionBackslashSequence
RegularExpressionFlags
::
[empty]
RegularExpressionFlags
IdentifierPartChar
Template ::
NoSubstitutionTemplate
TemplateHead
NoSubstitutionTemplate
::
`
TemplateCharacters opt
`
TemplateHead ::
`
TemplateCharacters opt
${
TemplateSubstitutionTail
::
TemplateMiddle
TemplateTail
TemplateMiddle ::
}
TemplateCharacters opt
${
TemplateTail ::
}
TemplateCharacters opt
`
TemplateCharacters ::
TemplateCharacter
TemplateCharacters opt
TemplateCharacter ::
$
[lookahead ≠ { ]
\
TemplateEscapeSequence
\
NotEscapeSequence
LineContinuation
LineTerminatorSequence
SourceCharacter but not one of
` or \ or $ or LineTerminator
TemplateEscapeSequence
::
CharacterEscapeSequence
0
[lookahead ∉ DecimalDigit ]
HexEscapeSequence
UnicodeEscapeSequence
NotEscapeSequence ::
0
DecimalDigit
DecimalDigit but not
0
x
[lookahead ∉ HexDigit ]
x
HexDigit
[lookahead ∉ HexDigit ]
u
[lookahead ∉ HexDigit ]
[lookahead ≠ { ]
u
HexDigit
[lookahead ∉ HexDigit ]
u
HexDigit
HexDigit
[lookahead ∉ HexDigit ]
u
HexDigit
HexDigit
HexDigit
[lookahead ∉ HexDigit ]
u
{
[lookahead ∉ HexDigit ]
u
{
NotCodePoint
[lookahead ∉ HexDigit ]
u
{
CodePoint
[lookahead ∉ HexDigit ]
[lookahead ≠ } ]
NotCodePoint ::
HexDigits [~Sep]
but only if the MV of HexDigits >
0x10FFFF
CodePoint ::
HexDigits [~Sep]
but only if the MV of HexDigits ≤
0x10FFFF
A.2 Expressions
IdentifierReference [Yield,
Await] :
Identifier
[~Yield]
yield
[~Await]
await
BindingIdentifier [Yield,
Await] :
Identifier
yield
await
LabelIdentifier [Yield,
Await] :
Identifier
[~Yield]
yield
[~Await]
await
Identifier :
IdentifierName but not ReservedWord
PrimaryExpression [Yield,
Await] :
this
IdentifierReference [?Yield,
?Await]
Literal
ArrayLiteral [?Yield,
?Await]
ObjectLiteral [?Yield,
?Await]
FunctionExpression
ClassExpression [?Yield,
?Await]
GeneratorExpression
AsyncFunctionExpression
AsyncGeneratorExpression
RegularExpressionLiteral
TemplateLiteral [?Yield, ?Await,
~Tagged]
CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
CoverParenthesizedExpressionAndArrowParameterList [Yield,
Await] :
(
Expression [+In, ?Yield,
?Await]
)
(
Expression [+In, ?Yield,
?Await]
,
)
(
)
(
...
BindingIdentifier [?Yield,
?Await]
)
(
...
BindingPattern [?Yield,
?Await]
)
(
Expression [+In, ?Yield,
?Await]
,
...
BindingIdentifier [?Yield,
?Await]
)
(
Expression [+In, ?Yield,
?Await]
,
...
BindingPattern [?Yield,
?Await]
)
When processing an instance of the production
PrimaryExpression [Yield,
Await] :
CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList
is refined using the following grammar:
ParenthesizedExpression [Yield,
Await] :
(
Expression [+In, ?Yield,
?Await]
)
Literal :
NullLiteral
BooleanLiteral
NumericLiteral
StringLiteral
ArrayLiteral [Yield,
Await] :
[
Elision opt
]
[
ElementList [?Yield,
?Await]
]
[
ElementList [?Yield,
?Await]
,
Elision opt
]
ElementList [Yield,
Await] :
Elision opt
AssignmentExpression [+In,
?Yield, ?Await]
Elision opt
SpreadElement [?Yield,
?Await]
ElementList [?Yield,
?Await]
,
Elision opt
AssignmentExpression [+In,
?Yield, ?Await]
ElementList [?Yield,
?Await]
,
Elision opt
SpreadElement [?Yield,
?Await]
Elision :
,
Elision
,
SpreadElement [Yield,
Await] :
...
AssignmentExpression [+In,
?Yield, ?Await]
ObjectLiteral [Yield,
Await] :
{
}
{
PropertyDefinitionList [?Yield,
?Await]
}
{
PropertyDefinitionList [?Yield,
?Await]
,
}
PropertyDefinitionList [Yield,
Await] :
PropertyDefinition [?Yield,
?Await]
PropertyDefinitionList [?Yield,
?Await]
,
PropertyDefinition [?Yield,
?Await]
PropertyDefinition [Yield,
Await] :
IdentifierReference [?Yield,
?Await]
CoverInitializedName [?Yield,
?Await]
PropertyName [?Yield,
?Await]
:
AssignmentExpression [+In,
?Yield, ?Await]
MethodDefinition [?Yield,
?Await]
...
AssignmentExpression [+In,
?Yield, ?Await]
PropertyName [Yield,
Await] :
LiteralPropertyName
ComputedPropertyName [?Yield,
?Await]
LiteralPropertyName :
IdentifierName
StringLiteral
NumericLiteral
ComputedPropertyName [Yield,
Await] :
[
AssignmentExpression [+In,
?Yield, ?Await]
]
CoverInitializedName [Yield,
Await] :
IdentifierReference [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await]
Initializer [In, Yield,
Await] :
=
AssignmentExpression [?In,
?Yield, ?Await]
TemplateLiteral [Yield, Await,
Tagged] :
NoSubstitutionTemplate
SubstitutionTemplate [?Yield,
?Await, ?Tagged]
SubstitutionTemplate [Yield,
Await, Tagged] :
TemplateHead
Expression [+In, ?Yield,
?Await]
TemplateSpans [?Yield, ?Await,
?Tagged]
TemplateSpans [Yield, Await,
Tagged] :
TemplateTail
TemplateMiddleList [?Yield,
?Await, ?Tagged]
TemplateTail
TemplateMiddleList [Yield, Await,
Tagged] :
TemplateMiddle
Expression [+In, ?Yield,
?Await]
TemplateMiddleList [?Yield,
?Await, ?Tagged]
TemplateMiddle
Expression [+In, ?Yield,
?Await]
MemberExpression [Yield,
Await] :
PrimaryExpression [?Yield,
?Await]
MemberExpression [?Yield,
?Await]
[
Expression [+In, ?Yield,
?Await]
]
MemberExpression [?Yield,
?Await]
.
IdentifierName
MemberExpression [?Yield,
?Await]
TemplateLiteral [?Yield, ?Await,
+Tagged]
SuperProperty [?Yield,
?Await]
MetaProperty
new
MemberExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
MemberExpression [?Yield,
?Await]
.
PrivateIdentifier
SuperProperty [Yield,
Await] :
super
[
Expression [+In, ?Yield,
?Await]
]
super
.
IdentifierName
MetaProperty :
NewTarget
ImportMeta
NewTarget :
new
.
target
ImportMeta :
import
.
meta
NewExpression [Yield,
Await] :
MemberExpression [?Yield,
?Await]
new
NewExpression [?Yield,
?Await]
CallExpression [Yield,
Await] :
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
SuperCall [?Yield,
?Await]
ImportCall [?Yield,
?Await]
CallExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
CallExpression [?Yield,
?Await]
[
Expression [+In, ?Yield,
?Await]
]
CallExpression [?Yield,
?Await]
.
IdentifierName
CallExpression [?Yield,
?Await]
TemplateLiteral [?Yield, ?Await,
+Tagged]
CallExpression [?Yield,
?Await]
.
PrivateIdentifier
When processing an instance of the production
CallExpression [Yield,
Await] :
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
the interpretation of CoverCallExpressionAndAsyncArrowHead
is refined using the following grammar:
CallMemberExpression [Yield,
Await] :
MemberExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
SuperCall [Yield,
Await] :
super
Arguments [?Yield,
?Await]
ImportCall [Yield,
Await] :
import
(
AssignmentExpression [+In,
?Yield, ?Await]
,opt
)
import
(
AssignmentExpression [+In,
?Yield, ?Await]
,
AssignmentExpression [+In,
?Yield, ?Await]
,opt
)
Arguments [Yield,
Await] :
(
)
(
ArgumentList [?Yield,
?Await]
)
(
ArgumentList [?Yield,
?Await]
,
)
ArgumentList [Yield,
Await] :
AssignmentExpression [+In,
?Yield, ?Await]
...
AssignmentExpression [+In,
?Yield, ?Await]
ArgumentList [?Yield,
?Await]
,
AssignmentExpression [+In,
?Yield, ?Await]
ArgumentList [?Yield,
?Await]
,
...
AssignmentExpression [+In,
?Yield, ?Await]
OptionalExpression [Yield,
Await] :
MemberExpression [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
CallExpression [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
OptionalExpression [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
OptionalChain [Yield,
Await] :
?.
Arguments [?Yield,
?Await]
?.
[
Expression [+In, ?Yield,
?Await]
]
?.
IdentifierName
?.
TemplateLiteral [?Yield, ?Await,
+Tagged]
?.
PrivateIdentifier
OptionalChain [?Yield,
?Await]
Arguments [?Yield,
?Await]
OptionalChain [?Yield,
?Await]
[
Expression [+In, ?Yield,
?Await]
]
OptionalChain [?Yield,
?Await]
.
IdentifierName
OptionalChain [?Yield,
?Await]
TemplateLiteral [?Yield, ?Await,
+Tagged]
OptionalChain [?Yield,
?Await]
.
PrivateIdentifier
LeftHandSideExpression [Yield,
Await] :
NewExpression [?Yield,
?Await]
CallExpression [?Yield,
?Await]
OptionalExpression [?Yield,
?Await]
UpdateExpression [Yield,
Await] :
LeftHandSideExpression [?Yield,
?Await]
LeftHandSideExpression [?Yield,
?Await]
[no LineTerminator
here]
++
LeftHandSideExpression [?Yield,
?Await]
[no LineTerminator
here]
--
++
UnaryExpression [?Yield,
?Await]
--
UnaryExpression [?Yield,
?Await]
UnaryExpression [Yield,
Await] :
UpdateExpression [?Yield,
?Await]
delete
UnaryExpression [?Yield,
?Await]
void
UnaryExpression [?Yield,
?Await]
typeof
UnaryExpression [?Yield,
?Await]
+
UnaryExpression [?Yield,
?Await]
-
UnaryExpression [?Yield,
?Await]
~
UnaryExpression [?Yield,
?Await]
!
UnaryExpression [?Yield,
?Await]
[+Await]
AwaitExpression [?Yield]
ExponentiationExpression [Yield,
Await] :
UnaryExpression [?Yield,
?Await]
UpdateExpression [?Yield,
?Await]
**
ExponentiationExpression [?Yield,
?Await]
MultiplicativeExpression [Yield,
Await] :
ExponentiationExpression [?Yield,
?Await]
MultiplicativeExpression [?Yield,
?Await]
MultiplicativeOperator
ExponentiationExpression [?Yield,
?Await]
MultiplicativeOperator
: one of * /
%
AdditiveExpression [Yield,
Await] :
MultiplicativeExpression [?Yield,
?Await]
AdditiveExpression [?Yield,
?Await]
+
MultiplicativeExpression [?Yield,
?Await]
AdditiveExpression [?Yield,
?Await]
-
MultiplicativeExpression [?Yield,
?Await]
ShiftExpression [Yield,
Await] :
AdditiveExpression [?Yield,
?Await]
ShiftExpression [?Yield,
?Await]
<<
AdditiveExpression [?Yield,
?Await]
ShiftExpression [?Yield,
?Await]
>>
AdditiveExpression [?Yield,
?Await]
ShiftExpression [?Yield,
?Await]
>>>
AdditiveExpression [?Yield,
?Await]
RelationalExpression [In, Yield,
Await] :
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
<
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
>
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
<=
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
>=
ShiftExpression [?Yield,
?Await]
RelationalExpression [?In,
?Yield, ?Await]
instanceof
ShiftExpression [?Yield,
?Await]
[+In]
RelationalExpression [+In,
?Yield, ?Await]
in
ShiftExpression [?Yield,
?Await]
[+In]
PrivateIdentifier
in
ShiftExpression [?Yield,
?Await]
EqualityExpression [In, Yield,
Await] :
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
==
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
!=
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
===
RelationalExpression [?In,
?Yield, ?Await]
EqualityExpression [?In,
?Yield, ?Await]
!==
RelationalExpression [?In,
?Yield, ?Await]
BitwiseANDExpression [In, Yield,
Await] :
EqualityExpression [?In,
?Yield, ?Await]
BitwiseANDExpression [?In,
?Yield, ?Await]
&
EqualityExpression [?In,
?Yield, ?Await]
BitwiseXORExpression [In, Yield,
Await] :
BitwiseANDExpression [?In,
?Yield, ?Await]
BitwiseXORExpression [?In,
?Yield, ?Await]
^
BitwiseANDExpression [?In,
?Yield, ?Await]
BitwiseORExpression [In, Yield,
Await] :
BitwiseXORExpression [?In,
?Yield, ?Await]
BitwiseORExpression [?In,
?Yield, ?Await]
|
BitwiseXORExpression [?In,
?Yield, ?Await]
LogicalANDExpression [In, Yield,
Await] :
BitwiseORExpression [?In,
?Yield, ?Await]
LogicalANDExpression [?In,
?Yield, ?Await]
&&
BitwiseORExpression [?In,
?Yield, ?Await]
LogicalORExpression [In, Yield,
Await] :
LogicalANDExpression [?In,
?Yield, ?Await]
LogicalORExpression [?In,
?Yield, ?Await]
||
LogicalANDExpression [?In,
?Yield, ?Await]
CoalesceExpression [In, Yield,
Await] :
CoalesceExpressionHead [?In,
?Yield, ?Await]
??
BitwiseORExpression [?In,
?Yield, ?Await]
CoalesceExpressionHead [In,
Yield, Await] :
CoalesceExpression [?In,
?Yield, ?Await]
BitwiseORExpression [?In,
?Yield, ?Await]
ShortCircuitExpression [In,
Yield, Await] :
LogicalORExpression [?In,
?Yield, ?Await]
CoalesceExpression [?In,
?Yield, ?Await]
ConditionalExpression [In,
Yield, Await] :
ShortCircuitExpression [?In,
?Yield, ?Await]
ShortCircuitExpression [?In,
?Yield, ?Await]
?
AssignmentExpression [+In,
?Yield, ?Await]
:
AssignmentExpression [?In,
?Yield, ?Await]
AssignmentExpression [In, Yield,
Await] :
ConditionalExpression [?In,
?Yield, ?Await]
[+Yield]
YieldExpression [?In,
?Await]
ArrowFunction [?In, ?Yield,
?Await]
AsyncArrowFunction [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
=
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
AssignmentOperator
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
&&=
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
||=
AssignmentExpression [?In,
?Yield, ?Await]
LeftHandSideExpression [?Yield,
?Await]
??=
AssignmentExpression [?In,
?Yield, ?Await]
AssignmentOperator :
one of *= /= %=
+= -= <<= >>=
>>>= &= ^= |=
**=
In certain circumstances when processing an instance of the production
AssignmentExpression [In,
Yield, Await] :
LeftHandSideExpression [?Yield,
?Await]
=
AssignmentExpression [?In,
?Yield, ?Await]
the interpretation of LeftHandSideExpression is refined using the
following grammar:
AssignmentPattern [Yield,
Await] :
ObjectAssignmentPattern [?Yield,
?Await]
ArrayAssignmentPattern [?Yield,
?Await]
ObjectAssignmentPattern [Yield,
Await] :
{
}
{
AssignmentRestProperty [?Yield,
?Await]
}
{
AssignmentPropertyList [?Yield,
?Await]
}
{
AssignmentPropertyList [?Yield,
?Await]
,
AssignmentRestProperty [?Yield,
?Await] opt
}
ArrayAssignmentPattern [Yield,
Await] :
[
Elision opt
AssignmentRestElement [?Yield,
?Await] opt
]
[
AssignmentElementList [?Yield,
?Await]
]
[
AssignmentElementList [?Yield,
?Await]
,
Elision opt
AssignmentRestElement [?Yield,
?Await] opt
]
AssignmentRestProperty [Yield,
Await] :
...
DestructuringAssignmentTarget [?Yield,
?Await]
AssignmentPropertyList [Yield,
Await] :
AssignmentProperty [?Yield,
?Await]
AssignmentPropertyList [?Yield,
?Await]
,
AssignmentProperty [?Yield,
?Await]
AssignmentElementList [Yield,
Await] :
AssignmentElisionElement [?Yield,
?Await]
AssignmentElementList [?Yield,
?Await]
,
AssignmentElisionElement [?Yield,
?Await]
AssignmentElisionElement [Yield,
Await] :
Elision opt
AssignmentElement [?Yield,
?Await]
AssignmentProperty [Yield,
Await] :
IdentifierReference [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
PropertyName [?Yield,
?Await]
:
AssignmentElement [?Yield,
?Await]
AssignmentElement [Yield,
Await] :
DestructuringAssignmentTarget [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
AssignmentRestElement [Yield,
Await] :
...
DestructuringAssignmentTarget [?Yield,
?Await]
DestructuringAssignmentTarget [Yield,
Await] :
LeftHandSideExpression [?Yield,
?Await]
Expression [In, Yield,
Await] :
AssignmentExpression [?In,
?Yield, ?Await]
Expression [?In, ?Yield,
?Await]
,
AssignmentExpression [?In,
?Yield, ?Await]
A.3 Statements
Statement [Yield, Await,
Return] :
BlockStatement [?Yield, ?Await,
?Return]
VariableStatement [?Yield,
?Await]
EmptyStatement
ExpressionStatement [?Yield,
?Await]
IfStatement [?Yield, ?Await,
?Return]
BreakableStatement [?Yield,
?Await, ?Return]
ContinueStatement [?Yield,
?Await]
BreakStatement [?Yield,
?Await]
[+Return]
ReturnStatement [?Yield,
?Await]
WithStatement [?Yield, ?Await,
?Return]
LabelledStatement [?Yield,
?Await, ?Return]
ThrowStatement [?Yield,
?Await]
TryStatement [?Yield, ?Await,
?Return]
DebuggerStatement
Declaration [Yield,
Await] :
HoistableDeclaration [?Yield,
?Await, ~Default]
ClassDeclaration [?Yield, ?Await,
~Default]
LexicalDeclaration [+In,
?Yield, ?Await]
HoistableDeclaration [Yield,
Await, Default] :
FunctionDeclaration [?Yield,
?Await, ?Default]
GeneratorDeclaration [?Yield,
?Await, ?Default]
AsyncFunctionDeclaration [?Yield,
?Await, ?Default]
AsyncGeneratorDeclaration [?Yield,
?Await, ?Default]
BreakableStatement [Yield, Await,
Return] :
IterationStatement [?Yield,
?Await, ?Return]
SwitchStatement [?Yield, ?Await,
?Return]
BlockStatement [Yield, Await,
Return] :
Block [?Yield, ?Await,
?Return]
Block [Yield,
Await, Return] :
{
StatementList [?Yield, ?Await,
?Return] opt
}
StatementList [Yield, Await,
Return] :
StatementListItem [?Yield,
?Await, ?Return]
StatementList [?Yield, ?Await,
?Return]
StatementListItem [?Yield,
?Await, ?Return]
StatementListItem [Yield, Await,
Return] :
Statement [?Yield, ?Await,
?Return]
Declaration [?Yield,
?Await]
LexicalDeclaration [In, Yield,
Await] :
LetOrConst
BindingList [?In, ?Yield,
?Await]
;
LetOrConst :
let
const
BindingList [In, Yield,
Await] :
LexicalBinding [?In, ?Yield,
?Await]
BindingList [?In, ?Yield,
?Await]
,
LexicalBinding [?In, ?Yield,
?Await]
LexicalBinding [In, Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await] opt
BindingPattern [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await]
VariableStatement [Yield,
Await] :
var
VariableDeclarationList [+In,
?Yield, ?Await]
;
VariableDeclarationList [In,
Yield, Await] :
VariableDeclaration [?In,
?Yield, ?Await]
VariableDeclarationList [?In,
?Yield, ?Await]
,
VariableDeclaration [?In,
?Yield, ?Await]
VariableDeclaration [In, Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await] opt
BindingPattern [?Yield,
?Await]
Initializer [?In, ?Yield,
?Await]
BindingPattern [Yield,
Await] :
ObjectBindingPattern [?Yield,
?Await]
ArrayBindingPattern [?Yield,
?Await]
ObjectBindingPattern [Yield,
Await] :
{
}
{
BindingRestProperty [?Yield,
?Await]
}
{
BindingPropertyList [?Yield,
?Await]
}
{
BindingPropertyList [?Yield,
?Await]
,
BindingRestProperty [?Yield,
?Await] opt
}
ArrayBindingPattern [Yield,
Await] :
[
Elision opt
BindingRestElement [?Yield,
?Await] opt
]
[
BindingElementList [?Yield,
?Await]
]
[
BindingElementList [?Yield,
?Await]
,
Elision opt
BindingRestElement [?Yield,
?Await] opt
]
BindingRestProperty [Yield,
Await] :
...
BindingIdentifier [?Yield,
?Await]
BindingPropertyList [Yield,
Await] :
BindingProperty [?Yield,
?Await]
BindingPropertyList [?Yield,
?Await]
,
BindingProperty [?Yield,
?Await]
BindingElementList [Yield,
Await] :
BindingElisionElement [?Yield,
?Await]
BindingElementList [?Yield,
?Await]
,
BindingElisionElement [?Yield,
?Await]
BindingElisionElement [Yield,
Await] :
Elision opt
BindingElement [?Yield,
?Await]
BindingProperty [Yield,
Await] :
SingleNameBinding [?Yield,
?Await]
PropertyName [?Yield,
?Await]
:
BindingElement [?Yield,
?Await]
BindingElement [Yield,
Await] :
SingleNameBinding [?Yield,
?Await]
BindingPattern [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
SingleNameBinding [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
BindingRestElement [Yield,
Await] :
...
BindingIdentifier [?Yield,
?Await]
...
BindingPattern [?Yield,
?Await]
EmptyStatement :
;
ExpressionStatement [Yield,
Await] :
[lookahead ∉ { { , function , async
[no LineTerminator
here]
function , class , let
[ }]
Expression [+In, ?Yield,
?Await]
;
IfStatement [Yield, Await,
Return] :
if
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
else
Statement [?Yield, ?Await,
?Return]
if
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
[lookahead ≠ else ]
IterationStatement [Yield, Await,
Return] :
DoWhileStatement [?Yield, ?Await,
?Return]
WhileStatement [?Yield, ?Await,
?Return]
ForStatement [?Yield, ?Await,
?Return]
ForInOfStatement [?Yield, ?Await,
?Return]
DoWhileStatement [Yield, Await,
Return] :
do
Statement [?Yield, ?Await,
?Return]
while
(
Expression [+In, ?Yield,
?Await]
)
;
WhileStatement [Yield, Await,
Return] :
while
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
ForStatement [Yield, Await,
Return] :
for
(
[lookahead ≠ let
[ ]
Expression [~In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
)
Statement [?Yield, ?Await,
?Return]
for
(
var
VariableDeclarationList [~In,
?Yield, ?Await]
;
Expression [+In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
)
Statement [?Yield, ?Await,
?Return]
for
(
LexicalDeclaration [~In,
?Yield, ?Await]
Expression [+In, ?Yield,
?Await] opt
;
Expression [+In, ?Yield,
?Await] opt
)
Statement [?Yield, ?Await,
?Return]
ForInOfStatement [Yield, Await,
Return] :
for
(
[lookahead ≠ let
[ ]
LeftHandSideExpression [?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
var
ForBinding [?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
ForDeclaration [?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
[lookahead ∉ { let , async
of }]
LeftHandSideExpression [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
var
ForBinding [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
for
(
ForDeclaration [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
[+Await]
for
await
(
[lookahead ≠ let ]
LeftHandSideExpression [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
[+Await]
for
await
(
var
ForBinding [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
[+Await]
for
await
(
ForDeclaration [?Yield,
?Await]
of
AssignmentExpression [+In,
?Yield, ?Await]
)
Statement [?Yield, ?Await,
?Return]
ForDeclaration [Yield,
Await] :
LetOrConst
ForBinding [?Yield,
?Await]
ForBinding [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
BindingPattern [?Yield,
?Await]
ContinueStatement [Yield,
Await] :
continue
;
continue
[no LineTerminator
here]
LabelIdentifier [?Yield,
?Await]
;
BreakStatement [Yield,
Await] :
break
;
break
[no LineTerminator
here]
LabelIdentifier [?Yield,
?Await]
;
ReturnStatement [Yield,
Await] :
return
;
return
[no LineTerminator
here]
Expression [+In, ?Yield,
?Await]
;
WithStatement [Yield, Await,
Return] :
with
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
SwitchStatement [Yield, Await,
Return] :
switch
(
Expression [+In, ?Yield,
?Await]
)
CaseBlock [?Yield, ?Await,
?Return]
CaseBlock [Yield, Await,
Return] :
{
CaseClauses [?Yield, ?Await,
?Return] opt
}
{
CaseClauses [?Yield, ?Await,
?Return] opt
DefaultClause [?Yield, ?Await,
?Return]
CaseClauses [?Yield, ?Await,
?Return] opt
}
CaseClauses [Yield, Await,
Return] :
CaseClause [?Yield, ?Await,
?Return]
CaseClauses [?Yield, ?Await,
?Return]
CaseClause [?Yield, ?Await,
?Return]
CaseClause [Yield, Await,
Return] :
case
Expression [+In, ?Yield,
?Await]
:
StatementList [?Yield, ?Await,
?Return] opt
DefaultClause [Yield, Await,
Return] :
default
:
StatementList [?Yield, ?Await,
?Return] opt
LabelledStatement [Yield, Await,
Return] :
LabelIdentifier [?Yield,
?Await]
:
LabelledItem [?Yield, ?Await,
?Return]
LabelledItem [Yield, Await,
Return] :
Statement [?Yield, ?Await,
?Return]
FunctionDeclaration [?Yield,
?Await, ~Default]
ThrowStatement [Yield,
Await] :
throw
[no LineTerminator
here]
Expression [+In, ?Yield,
?Await]
;
TryStatement [Yield, Await,
Return] :
try
Block [?Yield, ?Await,
?Return]
Catch [?Yield, ?Await,
?Return]
try
Block [?Yield, ?Await,
?Return]
Finally [?Yield, ?Await,
?Return]
try
Block [?Yield, ?Await,
?Return]
Catch [?Yield, ?Await,
?Return]
Finally [?Yield, ?Await,
?Return]
Catch [Yield,
Await, Return] :
catch
(
CatchParameter [?Yield,
?Await]
)
Block [?Yield, ?Await,
?Return]
catch
Block [?Yield, ?Await,
?Return]
Finally [Yield, Await,
Return] :
finally
Block [?Yield, ?Await,
?Return]
CatchParameter [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
BindingPattern [?Yield,
?Await]
DebuggerStatement :
debugger
;
A.4 Functions and Classes
UniqueFormalParameters [Yield,
Await] :
FormalParameters [?Yield,
?Await]
FormalParameters [Yield,
Await] :
[empty]
FunctionRestParameter [?Yield,
?Await]
FormalParameterList [?Yield,
?Await]
FormalParameterList [?Yield,
?Await]
,
FormalParameterList [?Yield,
?Await]
,
FunctionRestParameter [?Yield,
?Await]
FormalParameterList [Yield,
Await] :
FormalParameter [?Yield,
?Await]
FormalParameterList [?Yield,
?Await]
,
FormalParameter [?Yield,
?Await]
FunctionRestParameter [Yield,
Await] :
BindingRestElement [?Yield,
?Await]
FormalParameter [Yield,
Await] :
BindingElement [?Yield,
?Await]
FunctionDeclaration [Yield, Await,
Default] :
function
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
[+Default]
function
(
FormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
FunctionExpression :
function
BindingIdentifier [~Yield,
~Await] opt
(
FormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
FunctionBody [Yield,
Await] :
FunctionStatementList [?Yield,
?Await]
FunctionStatementList [Yield,
Await] :
StatementList [?Yield, ?Await,
+Return] opt
ArrowFunction [In, Yield,
Await] :
ArrowParameters [?Yield,
?Await]
[no LineTerminator
here]
=>
ConciseBody [?In]
ArrowParameters [Yield,
Await] :
BindingIdentifier [?Yield,
?Await]
CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
ConciseBody [In]
:
[lookahead ≠ { ]
ExpressionBody [?In,
~Await]
{
FunctionBody [~Yield,
~Await]
}
ExpressionBody [In,
Await] :
AssignmentExpression [?In,
~Yield, ?Await]
When processing an instance of the production
ArrowParameters [Yield,
Await] :
CoverParenthesizedExpressionAndArrowParameterList [?Yield,
?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList
is refined using the following grammar:
ArrowFormalParameters [Yield,
Await] :
(
UniqueFormalParameters [?Yield,
?Await]
)
AsyncArrowFunction [In, Yield,
Await] :
async
[no LineTerminator
here]
AsyncArrowBindingIdentifier [?Yield]
[no LineTerminator
here]
=>
AsyncConciseBody [?In]
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
[no LineTerminator
here]
=>
AsyncConciseBody [?In]
AsyncConciseBody [In]
:
[lookahead ≠ { ]
ExpressionBody [?In,
+Await]
{
AsyncFunctionBody
}
AsyncArrowBindingIdentifier [Yield]
:
BindingIdentifier [?Yield,
+Await]
CoverCallExpressionAndAsyncArrowHead [Yield,
Await] :
MemberExpression [?Yield,
?Await]
Arguments [?Yield,
?Await]
When processing an instance of the production
AsyncArrowFunction [In, Yield,
Await] :
CoverCallExpressionAndAsyncArrowHead [?Yield,
?Await]
[no LineTerminator
here]
=>
AsyncConciseBody [?In]
the interpretation of CoverCallExpressionAndAsyncArrowHead
is refined using the following grammar:
AsyncArrowHead :
async
[no LineTerminator
here]
ArrowFormalParameters [~Yield,
+Await]
MethodDefinition [Yield,
Await] :
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [~Yield,
~Await]
)
{
FunctionBody [~Yield,
~Await]
}
GeneratorMethod [?Yield,
?Await]
AsyncMethod [?Yield,
?Await]
AsyncGeneratorMethod [?Yield,
?Await]
get
ClassElementName [?Yield,
?Await]
(
)
{
FunctionBody [~Yield,
~Await]
}
set
ClassElementName [?Yield,
?Await]
(
PropertySetParameterList
)
{
FunctionBody [~Yield,
~Await]
}
PropertySetParameterList
:
FormalParameter [~Yield,
~Await]
GeneratorDeclaration [Yield,
Await, Default] :
function
*
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
[+Default]
function
*
(
FormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
GeneratorExpression :
function
*
BindingIdentifier [+Yield,
~Await] opt
(
FormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
GeneratorMethod [Yield,
Await] :
*
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [+Yield,
~Await]
)
{
GeneratorBody
}
GeneratorBody :
FunctionBody [+Yield,
~Await]
YieldExpression [In,
Await] :
yield
yield
[no LineTerminator
here]
AssignmentExpression [?In,
+Yield, ?Await]
yield
[no LineTerminator
here]
*
AssignmentExpression [?In,
+Yield, ?Await]
AsyncGeneratorDeclaration [Yield,
Await, Default] :
async
[no LineTerminator
here]
function
*
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
[+Default]
async
[no LineTerminator
here]
function
*
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorExpression
:
async
[no LineTerminator
here]
function
*
BindingIdentifier [+Yield,
+Await] opt
(
FormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorMethod [Yield,
Await] :
async
[no LineTerminator
here]
*
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [+Yield,
+Await]
)
{
AsyncGeneratorBody
}
AsyncGeneratorBody :
FunctionBody [+Yield,
+Await]
AsyncFunctionDeclaration [Yield,
Await, Default] :
async
[no LineTerminator
here]
function
BindingIdentifier [?Yield,
?Await]
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
[+Default]
async
[no LineTerminator
here]
function
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncFunctionExpression
:
async
[no LineTerminator
here]
function
BindingIdentifier [~Yield,
+Await] opt
(
FormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncMethod [Yield,
Await] :
async
[no LineTerminator
here]
ClassElementName [?Yield,
?Await]
(
UniqueFormalParameters [~Yield,
+Await]
)
{
AsyncFunctionBody
}
AsyncFunctionBody :
FunctionBody [~Yield,
+Await]
AwaitExpression [Yield]
:
await
UnaryExpression [?Yield,
+Await]
ClassDeclaration [Yield, Await,
Default] :
class
BindingIdentifier [?Yield,
?Await]
ClassTail [?Yield,
?Await]
[+Default]
class
ClassTail [?Yield,
?Await]
ClassExpression [Yield,
Await] :
class
BindingIdentifier [?Yield,
?Await] opt
ClassTail [?Yield,
?Await]
ClassTail [Yield,
Await] :
ClassHeritage [?Yield,
?Await] opt
{
ClassBody [?Yield,
?Await] opt
}
ClassHeritage [Yield,
Await] :
extends
LeftHandSideExpression [?Yield,
?Await]
ClassBody [Yield,
Await] :
ClassElementList [?Yield,
?Await]
ClassElementList [Yield,
Await] :
ClassElement [?Yield,
?Await]
ClassElementList [?Yield,
?Await]
ClassElement [?Yield,
?Await]
ClassElement [Yield,
Await] :
MethodDefinition [?Yield,
?Await]
static
MethodDefinition [?Yield,
?Await]
FieldDefinition [?Yield,
?Await]
;
static
FieldDefinition [?Yield,
?Await]
;
ClassStaticBlock
;
FieldDefinition [Yield,
Await] :
ClassElementName [?Yield,
?Await]
Initializer [+In, ?Yield,
?Await] opt
ClassElementName [Yield,
Await] :
PropertyName [?Yield,
?Await]
PrivateIdentifier
ClassStaticBlock :
static
{
ClassStaticBlockBody
}
ClassStaticBlockBody :
ClassStaticBlockStatementList
ClassStaticBlockStatementList
:
StatementList [~Yield, +Await,
~Return] opt
A.5 Scripts and Modules
Script :
ScriptBody opt
ScriptBody :
StatementList [~Yield, ~Await,
~Return]
Module :
ModuleBody opt
ModuleBody :
ModuleItemList
ModuleItemList :
ModuleItem
ModuleItemList
ModuleItem
ModuleItem :
ImportDeclaration
ExportDeclaration
StatementListItem [~Yield,
+Await, ~Return]
ModuleExportName :
IdentifierName
StringLiteral
ImportDeclaration :
import
ImportClause
FromClause
WithClause opt
;
import
ModuleSpecifier
WithClause opt
;
ImportClause :
ImportedDefaultBinding
NameSpaceImport
NamedImports
ImportedDefaultBinding
,
NameSpaceImport
ImportedDefaultBinding
,
NamedImports
ImportedDefaultBinding
:
ImportedBinding
NameSpaceImport :
*
as
ImportedBinding
NamedImports :
{
}
{
ImportsList
}
{
ImportsList
,
}
FromClause :
from
ModuleSpecifier
ImportsList :
ImportSpecifier
ImportsList
,
ImportSpecifier
ImportSpecifier :
ImportedBinding
ModuleExportName
as
ImportedBinding
ModuleSpecifier :
StringLiteral
ImportedBinding :
BindingIdentifier [~Yield,
+Await]
WithClause :
with
{
}
with
{
WithEntries
,opt
}
WithEntries :
AttributeKey
:
StringLiteral
AttributeKey
:
StringLiteral
,
WithEntries
AttributeKey :
IdentifierName
StringLiteral
ExportDeclaration :
export
ExportFromClause
FromClause
WithClause opt
;
export
NamedExports
;
export
VariableStatement [~Yield,
+Await]
export
Declaration [~Yield,
+Await]
export
default
HoistableDeclaration [~Yield,
+Await, +Default]
export
default
ClassDeclaration [~Yield, +Await,
+Default]
export
default
[lookahead ∉ { function , async
[no LineTerminator
here]
function , class }]
AssignmentExpression [+In,
~Yield, +Await]
;
ExportFromClause :
*
*
as
ModuleExportName
NamedExports
NamedExports :
{
}
{
ExportsList
}
{
ExportsList
,
}
ExportsList :
ExportSpecifier
ExportsList
,
ExportSpecifier
ExportSpecifier :
ModuleExportName
ModuleExportName
as
ModuleExportName
A.6 Number Conversions
StringNumericLiteral
:::
StrWhiteSpace opt
StrWhiteSpace opt
StrNumericLiteral
StrWhiteSpace opt
StrWhiteSpace :::
StrWhiteSpaceChar
StrWhiteSpace opt
StrWhiteSpaceChar :::
WhiteSpace
LineTerminator
StrNumericLiteral :::
StrDecimalLiteral
NonDecimalIntegerLiteral [~Sep]
StrDecimalLiteral :::
StrUnsignedDecimalLiteral
+
StrUnsignedDecimalLiteral
-
StrUnsignedDecimalLiteral
StrUnsignedDecimalLiteral
:::
Infinity
DecimalDigits [~Sep]
.
DecimalDigits [~Sep] opt
ExponentPart [~Sep] opt
.
DecimalDigits [~Sep]
ExponentPart [~Sep] opt
DecimalDigits [~Sep]
ExponentPart [~Sep] opt
All grammar symbols not explicitly defined by the StringNumericLiteral grammar have the
definitions used in the Lexical Grammar for numeric literals .
StringIntegerLiteral
:::
StrWhiteSpace opt
StrWhiteSpace opt
StrIntegerLiteral
StrWhiteSpace opt
StrIntegerLiteral :::
SignedInteger [~Sep]
NonDecimalIntegerLiteral [~Sep]
A.7 Time Zone Offset String Format
UTCOffset :::
ASCIISign
Hour
ASCIISign
Hour
HourSubcomponents [+Extended]
ASCIISign
Hour
HourSubcomponents [~Extended]
ASCIISign ::: one
of + -
Hour :::
0
DecimalDigit
1
DecimalDigit
20
21
22
23
HourSubcomponents [Extended]
:::
TimeSeparator [?Extended]
MinuteSecond
TimeSeparator [?Extended]
MinuteSecond
TimeSeparator [?Extended]
MinuteSecond
TemporalDecimalFraction opt
TimeSeparator [Extended]
::: [+Extended]
:
[~Extended]
[empty]
MinuteSecond :::
0
DecimalDigit
1
DecimalDigit
2
DecimalDigit
3
DecimalDigit
4
DecimalDigit
5
DecimalDigit
TemporalDecimalFraction
:::
TemporalDecimalSeparator
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
DecimalDigit
TemporalDecimalSeparator
::: one of .
,
A.8 Regular Expressions
Pattern [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Disjunction [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
Alternative [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Alternative [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
|
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Alternative [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
[empty]
Alternative [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Term [?UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Term [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
Assertion [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
Atom [?UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Atom [?UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Quantifier
Assertion [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
^
$
\b
\B
(?=
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?!
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?<=
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?<!
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
Quantifier ::
QuantifierPrefix
QuantifierPrefix
?
QuantifierPrefix ::
*
+
?
{
DecimalDigits [~Sep]
}
{
DecimalDigits [~Sep]
,}
{
DecimalDigits [~Sep]
,
DecimalDigits [~Sep]
}
Atom [UnicodeMode, UnicodeSetsMode,
NamedCaptureGroups] ::
PatternCharacter
.
\
AtomEscape [?UnicodeMode,
?NamedCaptureGroups]
CharacterClass [?UnicodeMode,
?UnicodeSetsMode]
(
GroupSpecifier [?UnicodeMode] opt
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?
RegularExpressionModifiers
:
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?
RegularExpressionModifiers
-
RegularExpressionModifiers
:
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
RegularExpressionModifiers
::
[empty]
RegularExpressionModifiers
RegularExpressionModifier
RegularExpressionModifier
:: one of i m
s
SyntaxCharacter ::
one of ^ $ \
. * + ? (
) [ ] { }
|
PatternCharacter ::
SourceCharacter but not
SyntaxCharacter
AtomEscape [UnicodeMode,
NamedCaptureGroups] ::
DecimalEscape
CharacterClassEscape [?UnicodeMode]
CharacterEscape [?UnicodeMode]
[+NamedCaptureGroups]
k
GroupName [?UnicodeMode]
CharacterEscape [UnicodeMode]
::
ControlEscape
c
AsciiLetter
0
[lookahead ∉ DecimalDigit ]
HexEscapeSequence
RegExpUnicodeEscapeSequence [?UnicodeMode]
IdentityEscape [?UnicodeMode]
ControlEscape ::
one of f n r
t v
GroupSpecifier [UnicodeMode]
::
?
GroupName [?UnicodeMode]
GroupName [UnicodeMode]
::
<
RegExpIdentifierName [?UnicodeMode]
>
RegExpIdentifierName [UnicodeMode]
::
RegExpIdentifierStart [?UnicodeMode]
RegExpIdentifierName [?UnicodeMode]
RegExpIdentifierPart [?UnicodeMode]
RegExpIdentifierStart [UnicodeMode]
::
IdentifierStartChar
\
RegExpUnicodeEscapeSequence [+UnicodeMode]
[~UnicodeMode]
UnicodeLeadSurrogate
UnicodeTrailSurrogate
RegExpIdentifierPart [UnicodeMode]
::
IdentifierPartChar
\
RegExpUnicodeEscapeSequence [+UnicodeMode]
[~UnicodeMode]
UnicodeLeadSurrogate
UnicodeTrailSurrogate
RegExpUnicodeEscapeSequence [UnicodeMode]
:: [+UnicodeMode]
u
HexLeadSurrogate
\u
HexTrailSurrogate
[+UnicodeMode]
u
HexLeadSurrogate
[+UnicodeMode]
u
HexTrailSurrogate
[+UnicodeMode]
u
HexNonSurrogate
[~UnicodeMode]
u
Hex4Digits
[+UnicodeMode]
u{
CodePoint
}
UnicodeLeadSurrogate ::
any Unicode code point in the inclusive interval from U+D800 to U+DBFF
UnicodeTrailSurrogate
::
any Unicode code point in the inclusive interval from U+DC00 to U+DFFF
Each \u HexTrailSurrogate for which the choice of
associated u HexLeadSurrogate is ambiguous shall be associated
with the nearest possible u HexLeadSurrogate that would otherwise have no
corresponding \u HexTrailSurrogate .
HexLeadSurrogate ::
Hex4Digits
but only if the MV of Hex4Digits is in
the inclusive
interval from 0xD800 to 0xDBFF
HexTrailSurrogate ::
Hex4Digits
but only if the MV of Hex4Digits is in
the inclusive
interval from 0xDC00 to 0xDFFF
HexNonSurrogate ::
Hex4Digits
but only if the MV of Hex4Digits is
not in the inclusive
interval from 0xD800 to 0xDFFF
IdentityEscape [UnicodeMode]
:: [+UnicodeMode]
SyntaxCharacter
[+UnicodeMode]
/
[~UnicodeMode]
SourceCharacter but not
UnicodeIDContinue
DecimalEscape ::
NonZeroDigit
DecimalDigits [~Sep] opt
[lookahead ∉ DecimalDigit ]
CharacterClassEscape [UnicodeMode]
::
d
D
s
S
w
W
[+UnicodeMode]
p{
UnicodePropertyValueExpression
}
[+UnicodeMode]
P{
UnicodePropertyValueExpression
}
UnicodePropertyValueExpression
::
UnicodePropertyName
=
UnicodePropertyValue
LoneUnicodePropertyNameOrValue
UnicodePropertyName ::
UnicodePropertyNameCharacters
UnicodePropertyNameCharacters
::
UnicodePropertyNameCharacter
UnicodePropertyNameCharacters opt
UnicodePropertyValue ::
UnicodePropertyValueCharacters
LoneUnicodePropertyNameOrValue
::
UnicodePropertyValueCharacters
UnicodePropertyValueCharacters
::
UnicodePropertyValueCharacter
UnicodePropertyValueCharacters opt
UnicodePropertyValueCharacter
::
UnicodePropertyNameCharacter
DecimalDigit
UnicodePropertyNameCharacter
::
AsciiLetter
_
CharacterClass [UnicodeMode,
UnicodeSetsMode] ::
[
[lookahead ≠ ^ ]
ClassContents [?UnicodeMode,
?UnicodeSetsMode]
]
[^
ClassContents [?UnicodeMode,
?UnicodeSetsMode]
]
ClassContents [UnicodeMode,
UnicodeSetsMode] ::
[empty]
[~UnicodeSetsMode]
NonemptyClassRanges [?UnicodeMode]
[+UnicodeSetsMode]
ClassSetExpression
NonemptyClassRanges [UnicodeMode]
::
ClassAtom [?UnicodeMode]
ClassAtom [?UnicodeMode]
NonemptyClassRangesNoDash [?UnicodeMode]
ClassAtom [?UnicodeMode]
-
ClassAtom [?UnicodeMode]
ClassContents [?UnicodeMode,
~UnicodeSetsMode]
NonemptyClassRangesNoDash [UnicodeMode]
::
ClassAtom [?UnicodeMode]
ClassAtomNoDash [?UnicodeMode]
NonemptyClassRangesNoDash [?UnicodeMode]
ClassAtomNoDash [?UnicodeMode]
-
ClassAtom [?UnicodeMode]
ClassContents [?UnicodeMode,
~UnicodeSetsMode]
ClassAtom [UnicodeMode]
::
-
ClassAtomNoDash [?UnicodeMode]
ClassAtomNoDash [UnicodeMode]
::
SourceCharacter but not one of
\ or ] or -
\
ClassEscape [?UnicodeMode]
ClassEscape [UnicodeMode]
::
b
[+UnicodeMode]
-
CharacterClassEscape [?UnicodeMode]
CharacterEscape [?UnicodeMode]
ClassSetExpression ::
ClassUnion
ClassIntersection
ClassSubtraction
ClassUnion ::
ClassSetRange
ClassUnion opt
ClassSetOperand
ClassUnion opt
ClassIntersection ::
ClassSetOperand
&&
[lookahead ≠ & ]
ClassSetOperand
ClassIntersection
&&
[lookahead ≠ & ]
ClassSetOperand
ClassSubtraction ::
ClassSetOperand
--
ClassSetOperand
ClassSubtraction
--
ClassSetOperand
ClassSetRange ::
ClassSetCharacter
-
ClassSetCharacter
ClassSetOperand ::
NestedClass
ClassStringDisjunction
ClassSetCharacter
NestedClass ::
[
[lookahead ≠ ^ ]
ClassContents [+UnicodeMode,
+UnicodeSetsMode]
]
[^
ClassContents [+UnicodeMode,
+UnicodeSetsMode]
]
\
CharacterClassEscape [+UnicodeMode]
ClassStringDisjunction
::
\q{
ClassStringDisjunctionContents
}
ClassStringDisjunctionContents
::
ClassString
ClassString
|
ClassStringDisjunctionContents
ClassString ::
[empty]
NonEmptyClassString
NonEmptyClassString ::
ClassSetCharacter
NonEmptyClassString opt
ClassSetCharacter ::
[lookahead ∉ ClassSetReservedDoublePunctuator ]
SourceCharacter but not
ClassSetSyntaxCharacter
\
CharacterEscape [+UnicodeMode]
\
ClassSetReservedPunctuator
\b
ClassSetReservedDoublePunctuator
:: one of &&
!! ## $$ %% **
++ ,, .. :: ;;
<< == >> ??
@@ ^^ `` ~~
ClassSetSyntaxCharacter
:: one of ( )
[ ] { } /
- \ |
ClassSetReservedPunctuator
:: one of & -
! # % , :
; < = > @
` ~
Annex B (normative) Additional ECMAScript
Features for Web Browsers
The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript
host is a web browser. The content
of this annex is normative but optional if the ECMAScript host is not a web browser.
Note
This annex describes various legacy features and other characteristics of web browser ECMAScript
hosts . All of the language
features and behaviours specified in this annex have one or more undesirable characteristics and
in the absence of legacy usage would be removed from this specification. However, the usage of
these features by large numbers of existing web pages means that web browsers must continue to
support them. The specifications in this annex define the requirements for interoperable
implementations of these legacy features.
These features are not considered part of the core ECMAScript language. Programmers should not
use or assume the existence of these features and behaviours when writing new ECMAScript code.
ECMAScript implementations are discouraged from implementing these features unless the
implementation is part of a web browser or is required to run the same legacy ECMAScript code
that web browsers encounter.
B.1 Additional Syntax
B.1.2 Regular Expressions Patterns
The syntax of 22.2.1 is modified and extended as follows. These
changes introduce ambiguities that are broken by the ordering of grammar productions and by
contextual information. When parsing using the following grammar, each alternative is considered
only if previous production alternatives do not match.
This alternative pattern grammar and semantics only changes the syntax and semantics of BMP
patterns. The following grammar extensions include productions parameterized with the
[UnicodeMode] parameter. However, none of these extensions change the syntax of Unicode patterns
recognized when parsing with the [UnicodeMode] parameter present on the goal
symbol .
Syntax
Term [UnicodeMode,
UnicodeSetsMode, NamedCaptureGroups]
:: [+UnicodeMode]
Assertion [+UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
[+UnicodeMode]
Atom [+UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
Quantifier
[+UnicodeMode]
Atom [+UnicodeMode, ?UnicodeSetsMode,
?NamedCaptureGroups]
[~UnicodeMode]
QuantifiableAssertion [?NamedCaptureGroups]
Quantifier
[~UnicodeMode]
Assertion [~UnicodeMode,
~UnicodeSetsMode, ?NamedCaptureGroups]
[~UnicodeMode]
ExtendedAtom [?NamedCaptureGroups]
Quantifier
[~UnicodeMode]
ExtendedAtom [?NamedCaptureGroups]
Assertion [UnicodeMode,
UnicodeSetsMode, NamedCaptureGroups]
::
^
$
\b
\B
[+UnicodeMode]
(?=
Disjunction [+UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
[+UnicodeMode]
(?!
Disjunction [+UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
[~UnicodeMode]
QuantifiableAssertion [?NamedCaptureGroups]
(?<=
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
(?<!
Disjunction [?UnicodeMode,
?UnicodeSetsMode, ?NamedCaptureGroups]
)
QuantifiableAssertion [NamedCaptureGroups]
::
(?=
Disjunction [~UnicodeMode,
~UnicodeSetsMode, ?NamedCaptureGroups]
)
(?!
Disjunction [~UnicodeMode,
~UnicodeSetsMode, ?NamedCaptureGroups]
)
ExtendedAtom [NamedCaptureGroups]
::
.
\
AtomEscape [~UnicodeMode,
?NamedCaptureGroups]
\
[lookahead = c ]
CharacterClass [~UnicodeMode,
~UnicodeSetsMode]
(
GroupSpecifier [~UnicodeMode] opt
Disjunction [~UnicodeMode,
~UnicodeSetsMode, ?NamedCaptureGroups]
)
(?
RegularExpressionModifiers
:
Disjunction [~UnicodeMode,
~UnicodeSetsMode, ?NamedCaptureGroups]
)
(?
RegularExpressionModifiers
-
RegularExpressionModifiers
:
Disjunction [~UnicodeMode,
~UnicodeSetsMode, ?NamedCaptureGroups]
)
InvalidBracedQuantifier
ExtendedPatternCharacter
InvalidBracedQuantifier
::
{
DecimalDigits [~Sep]
}
{
DecimalDigits [~Sep]
,}
{
DecimalDigits [~Sep]
,
DecimalDigits [~Sep]
}
ExtendedPatternCharacter
::
SourceCharacter
but not one of ^
$
\
.
*
+
?
(
)
[
|
AtomEscape [UnicodeMode,
NamedCaptureGroups] ::
[+UnicodeMode]
DecimalEscape
[~UnicodeMode]
DecimalEscape
but only if the CapturingGroupNumber
of DecimalEscape
is ≤ CountLeftCapturingParensWithin (the
Pattern containing
DecimalEscape )
CharacterClassEscape [?UnicodeMode]
CharacterEscape [?UnicodeMode,
?NamedCaptureGroups]
[+NamedCaptureGroups]
k
GroupName [?UnicodeMode]
CharacterEscape [UnicodeMode,
NamedCaptureGroups] ::
ControlEscape
c
AsciiLetter
0
[lookahead ∉ DecimalDigit ]
HexEscapeSequence
RegExpUnicodeEscapeSequence [?UnicodeMode]
[~UnicodeMode]
LegacyOctalEscapeSequence
IdentityEscape [?UnicodeMode,
?NamedCaptureGroups]
IdentityEscape [UnicodeMode,
NamedCaptureGroups] ::
[+UnicodeMode]
SyntaxCharacter
[+UnicodeMode]
/
[~UnicodeMode]
SourceCharacterIdentityEscape [?NamedCaptureGroups]
SourceCharacterIdentityEscape [NamedCaptureGroups]
:: [~NamedCaptureGroups]
SourceCharacter
but not c
[+NamedCaptureGroups]
SourceCharacter
but not one of c or k
ClassAtomNoDash [UnicodeMode,
NamedCaptureGroups] ::
SourceCharacter
but not one of \ or ] or
-
\
ClassEscape [?UnicodeMode,
?NamedCaptureGroups]
\
[lookahead = c ]
ClassEscape [UnicodeMode,
NamedCaptureGroups] ::
b
[+UnicodeMode]
-
[~UnicodeMode]
c
ClassControlLetter
CharacterClassEscape [?UnicodeMode]
CharacterEscape [?UnicodeMode,
?NamedCaptureGroups]
ClassControlLetter
::
DecimalDigit
_
Note
When the same left-hand sides occurs with both [+UnicodeMode] and [~UnicodeMode] guards
it is to control the disambiguation priority.
B.1.2.1 Static Semantics: Early Errors
The semantics of 22.2.1.1 is
extended as follows:
ExtendedAtom
:: InvalidBracedQuantifier
It is a Syntax Error if any source text is matched by this production.
Additionally, the rules for the following productions are modified with the addition of the
highlighted text:
NonemptyClassRanges
::
ClassAtom
-
ClassAtom
ClassContents
NonemptyClassRangesNoDash
::
ClassAtomNoDash
-
ClassAtom
ClassContents
B.1.2.2 Static Semantics: CountLeftCapturingParensWithin and
CountLeftCapturingParensBefore
In the definitions of CountLeftCapturingParensWithin
and CountLeftCapturingParensBefore ,
references to “
Atom ::
(
GroupSpecifier opt
Disjunction
)
” are to be interpreted as meaning “
Atom ::
(
GroupSpecifier opt
Disjunction
)
” or “
ExtendedAtom
::
(
GroupSpecifier opt
Disjunction
)
”.
B.1.2.3 Static Semantics: IsCharacterClass
The semantics of 22.2.1.6 is
extended as follows:
ClassAtomNoDash
::
\
[lookahead = c ]
Return false .
B.1.2.4 Static Semantics: CharacterValue
The semantics of 22.2.1.7 is
extended as follows:
ClassAtomNoDash
::
\
[lookahead = c ]
Return the numeric value of U+005C (REVERSE SOLIDUS).
ClassEscape
::
c
ClassControlLetter
Let ch be the code point matched by ClassControlLetter .
Let i be the numeric value of ch .
Return the remainder of dividing i by 32.
CharacterEscape
:: LegacyOctalEscapeSequence
Return the MV of LegacyOctalEscapeSequence
(see 12.9.4.3 ).
B.1.2.5 Runtime Semantics: CompileSubpattern
The semantics of CompileSubpattern is extended as
follows:
The rule for
Term ::
QuantifiableAssertion
Quantifier
is the same as for
Term ::
Atom
Quantifier
but with QuantifiableAssertion
substituted for Atom .
The rule for
Term ::
ExtendedAtom
Quantifier
is the same as for
Term ::
Atom
Quantifier
but with ExtendedAtom substituted for Atom .
The rule for
Term :: ExtendedAtom
is the same as for
Term :: Atom
but with ExtendedAtom substituted for Atom .
B.1.2.6 Runtime Semantics: CompileAssertion
CompileAssertion rules for the
Assertion
::
(?=
Disjunction
)
and
Assertion
::
(?!
Disjunction
)
productions are also used for the QuantifiableAssertion
productions, but with QuantifiableAssertion
substituted for Assertion .
B.1.2.7 Runtime Semantics: CompileAtom
CompileAtom rules for the Atom productions except for
Atom :: PatternCharacter
are also used for the ExtendedAtom productions, but with
ExtendedAtom
substituted for Atom . The
following rules, with parameter direction , are also added:
ExtendedAtom
::
\
[lookahead = c ]
Let A be the CharSet containing the single
character \ U+005C (REVERSE SOLIDUS).
Return CharacterSetMatcher (rer ,
A , false , direction ).
ExtendedAtom
:: ExtendedPatternCharacter
Let ch be the character represented by ExtendedPatternCharacter .
Let A be a one-element CharSet containing the
character ch .
Return CharacterSetMatcher (rer ,
A , false , direction ).
B.1.2.8 Runtime Semantics: CompileToCharSet
The semantics of 22.2.2.9 is extended as follows:
The following two rules replace the corresponding rules of CompileToCharSet .
NonemptyClassRanges
::
ClassAtom
-
ClassAtom
ClassContents
Let A be CompileToCharSet of the first
ClassAtom with
argument rer .
Let B be CompileToCharSet of the second
ClassAtom with
argument rer .
Let C be CompileToCharSet of ClassContents with
argument rer .
Let D be CharacterRangeOrUnion (rer ,
A , B ).
Return the union of D and C .
NonemptyClassRangesNoDash
::
ClassAtomNoDash
-
ClassAtom
ClassContents
Let A be CompileToCharSet of ClassAtomNoDash with
argument rer .
Let B be CompileToCharSet of ClassAtom with argument
rer .
Let C be CompileToCharSet of ClassContents with
argument rer .
Let D be CharacterRangeOrUnion (rer ,
A , B ).
Return the union of D and C .
In addition, the following rules are added to CompileToCharSet .
ClassEscape
::
c
ClassControlLetter
Let cv be the CharacterValue
of this ClassEscape .
Let c be the character whose character value is cv .
Return the CharSet containing the single
character c .
ClassAtomNoDash
::
\
[lookahead = c ]
Return the CharSet containing the single
character \ U+005C (REVERSE SOLIDUS).
Note
This production can only be reached from the sequence
\c within a character class where it is not followed by an acceptable
control character.
B.1.2.8.1 CharacterRangeOrUnion ( rer ,
A , B )
The abstract operation CharacterRangeOrUnion takes arguments rer (a RegExp
Record ), A (a CharSet ), and B
(a CharSet ) and returns a CharSet . It performs the following steps
when called:
If HasEitherUnicodeFlag (rer )
is false , then
If A does not contain exactly one character or B
does not contain exactly one character, then
Let C be the CharSet
containing the single character - U+002D
(HYPHEN-MINUS).
Return the union of CharSets
A , B and C .
Return CharacterRange (A ,
B ).
B.1.2.9 Static Semantics: ParsePattern ( patternText ,
u , v )
The semantics of 22.2.3.4 is extended as follows:
The abstract operation ParsePattern takes arguments
patternText (a sequence of Unicode code points), u (a Boolean), and
v (a Boolean). It performs the following steps when called:
If v is true and u is
true , then
Let parseResult be a List
containing one or more SyntaxError objects.
Else if v is true , then
Let parseResult be ParseText (patternText ,
Pattern [+UnicodeMode,
+UnicodeSetsMode,
+NamedCaptureGroups] ).
Else if u is true , then
Let parseResult be ParseText (patternText ,
Pattern [+UnicodeMode,
~UnicodeSetsMode,
+NamedCaptureGroups] ).
Else,
Let parseResult be ParseText (patternText ,
Pattern [~UnicodeMode,
~UnicodeSetsMode,
~NamedCaptureGroups] ).
If parseResult is a Parse
Node and parseResult contains a GroupName , then
Set parseResult to ParseText (patternText ,
Pattern [~UnicodeMode,
~UnicodeSetsMode,
+NamedCaptureGroups] ).
Return parseResult .
B.2 Additional Built-in Properties
When the ECMAScript host is a
web browser the following additional properties of the standard built-in objects are defined.
B.2.1 Additional Properties of the Global Object
The entries in Table 102 are added
to Table 6 .
Table 102: Additional Well-known Intrinsic Objects
B.2.1.1 escape ( string )
This function is a property of the global object . It computes a new version of
a String value in which certain code units have been replaced by a hexadecimal escape
sequence.
When replacing a code unit of numeric value less than or equal to 0x00FF, a two-digit escape
sequence of the form %xx is used. When replacing a code unit of
numeric value strictly greater than 0x00FF, a four-digit escape sequence of the form
%uxxxx is used.
It is the %escape% intrinsic object.
It performs the following steps when called:
Set string to ? ToString (string ).
Let len be the length of string .
Let R be the empty String.
Let unescapedSet be the string-concatenation of
the ASCII word characters and
"@*+-./" .
Let k be 0.
Repeat, while k < len ,
Let C be the code unit at index k within
string .
If unescapedSet contains C , then
Let S be C .
Else,
Let n be the numeric value of C .
If n < 256, then
Let hex be the String representation of
n , formatted as an uppercase hexadecimal number.
Let S be the string-concatenation
of "%" and StringPad (hex ,
2, "0" , start ).
Else,
Let hex be the String representation of
n , formatted as an uppercase hexadecimal number.
Let S be the string-concatenation
of "%u" and StringPad (hex ,
4, "0" , start ).
Set R to the string-concatenation of
R and S .
Set k to k + 1.
Return R .
Note
The encoding is partly based on the encoding described in RFC 1738, but the entire
encoding specified in this standard is described above without regard to the
contents of RFC 1738. This encoding does not reflect changes to RFC 1738 made by RFC
3986.
B.2.1.2 unescape ( string )
This function is a property of the global object . It computes a new version of
a String value in which each escape sequence of the sort that might be introduced by the
escape function is replaced with the code unit that it represents.
It is the %unescape% intrinsic object.
It performs the following steps when called:
Set string to ? ToString (string ).
Let len be the length of string .
Let R be the empty String.
Let k be 0.
Repeat, while k < len ,
Let C be the code unit at index k within
string .
If C is the code unit 0x0025 (PERCENT SIGN), then
Let hexDigits be the empty String.
Let optionalAdvance be 0.
If k + 5 < len and the code unit at index
k + 1 within string is the code unit 0x0075
(LATIN SMALL LETTER U), then
Set hexDigits to the substring of
string from k + 2 to k + 6.
Set optionalAdvance to 5.
Else if k + 3 ≤ len , then
Set hexDigits to the substring of
string from k + 1 to k + 3.
Set optionalAdvance to 2.
Let parseResult be ParseText (hexDigits ,
HexDigits [~Sep] ).
If parseResult is a Parse Node ,
then
Let n be the MV of parseResult .
Set C to the code unit whose numeric value is
n .
Set k to k +
optionalAdvance .
Set R to the string-concatenation of
R and C .
Set k to k + 1.
Return R .
B.2.2 Additional Properties of the String.prototype Object
B.2.2.1 String.prototype.substr ( start ,
length )
This method returns a substring of the result of converting the
this value to a String, starting from index start and running
for length code units (or through the end of the String if length is
undefined ). If start is negative, it is treated as sourceLength + start where
sourceLength is the length of the String. The result is a String value,
not a String object.
It performs the following steps when called:
Let O be ? RequireObjectCoercible (this
value).
Let S be ? ToString (O ).
Let size be the length of S .
Let intStart be ? ToIntegerOrInfinity (start ).
If intStart = -∞, set intStart to 0.
Else if intStart < 0, set intStart to max (size +
intStart , 0).
Else, set intStart to min (intStart , size ).
If length is undefined , let intLength be
size ; otherwise let intLength be ? ToIntegerOrInfinity (length ).
Set intLength to the result of clamping intLength
between 0 and size .
Let intEnd be min (intStart +
intLength , size ).
Return the substring of S from
intStart to intEnd .
Note
This method is intentionally generic; it does not require that its
this value be a String object. Therefore it can be transferred to
other kinds of objects for use as a method.
B.2.2.2 String.prototype.anchor ( name )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"a" , "name" , name ).
B.2.2.2.1 CreateHTML ( string , tag ,
attribute , value )
The abstract operation CreateHTML takes arguments string (an ECMAScript language value ),
tag (a String), attribute (a String), and value (an
ECMAScript language value )
and returns either a normal
completion containing a String or a throw
completion . It performs the following steps when called:
Let str be ? RequireObjectCoercible (string ).
Let S be ? ToString (str ).
Let p1 be the string-concatenation of
"<" and tag .
If attribute is not the empty String, then
Let V be ? ToString (value ).
Let escapedV be the String value that is the same as
V except that each occurrence of the code unit 0x0022
(QUOTATION MARK) in V has been replaced with the six code
unit sequence """ .
Set p1 to the string-concatenation
of:
p1
the code unit 0x0020 (SPACE)
attribute
the code unit 0x003D (EQUALS SIGN)
the code unit 0x0022 (QUOTATION MARK)
escapedV
the code unit 0x0022 (QUOTATION MARK)
Let p2 be the string-concatenation of
p1 and ">" .
Let p3 be the string-concatenation of
p2 and S .
Let p4 be the string-concatenation of
p3 , "</" , tag , and
">" .
Return p4 .
B.2.2.3 String.prototype.big ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"big" , "" , "" ).
B.2.2.4 String.prototype.blink ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"blink" , "" , "" ).
B.2.2.5 String.prototype.bold ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"b" , "" , "" ).
B.2.2.6 String.prototype.fixed ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"tt" , "" , "" ).
B.2.2.7 String.prototype.fontcolor ( colour )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"font" , "color" , colour ).
B.2.2.8 String.prototype.fontsize ( size )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"font" , "size" , size ).
B.2.2.9 String.prototype.italics ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"i" , "" , "" ).
B.2.2.10 String.prototype.link ( url )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"a" , "href" , url ).
B.2.2.11 String.prototype.small ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"small" , "" , "" ).
B.2.2.12 String.prototype.strike ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"strike" , "" , "" ).
B.2.2.13 String.prototype.sub ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"sub" , "" , "" ).
B.2.2.14 String.prototype.sup ( )
This method performs the following steps when called:
Let S be the this value.
Return ? CreateHTML (S ,
"sup" , "" , "" ).
B.2.2.15 String.prototype.trimLeft ( )
Note
The property "trimStart" is preferred. The
"trimLeft" property is provided principally for compatibility
with old code. It is recommended that the "trimStart" property be
used in new ECMAScript code.
The initial value of the "trimLeft" property is
%String.prototype.trimStart%, defined in 22.1.3.34 .
B.2.2.16 String.prototype.trimRight ( )
Note
The property "trimEnd" is preferred. The
"trimRight" property is provided principally for compatibility
with old code. It is recommended that the "trimEnd" property be
used in new ECMAScript code.
The initial value of the "trimRight" property is
%String.prototype.trimEnd%, defined in 22.1.3.33 .
B.2.3 Additional Properties of the Date.prototype Object
B.2.3.1 Date.prototype.getYear ( )
Note
The getFullYear method is preferred for nearly all purposes, because it
avoids the “year 2000 problem.”
This method performs the following steps when called:
Let dateObject be the this value.
Perform ? RequireInternalSlot (dateObject ,
[[DateValue]] ).
Let t be dateObject .[[DateValue]] .
If t is NaN , return NaN .
Return YearFromTime (LocalTime (t )) -
1900 𝔽 .
B.2.3.2 Date.prototype.setYear ( year )
Note
The setFullYear method is preferred for nearly all purposes, because it
avoids the “year 2000 problem.”
This method performs the following steps when called:
Let dateObject be the this value.
Perform ? RequireInternalSlot (dateObject ,
[[DateValue]] ).
Let t be dateObject .[[DateValue]] .
Let y be ? ToNumber (year ).
If t is NaN , set t to
+0 𝔽 ; otherwise, set t to LocalTime (t ).
Let yyyy be MakeFullYear (y ).
Let d be MakeDay (yyyy , MonthFromTime (t ),
DateFromTime (t )).
Let date be MakeDate (d , TimeWithinDay (t )).
Let u be TimeClip (UTC (date )).
Set dateObject .[[DateValue]] to u .
Return u .
B.2.3.3 Date.prototype.toGMTString ( )
Note
The toUTCString method is preferred. This method is provided principally
for compatibility with old code.
The initial value of the "toGMTString" property is
%Date.prototype.toUTCString%, defined in 21.4.4.43 .
B.2.4 Additional Properties of the RegExp.prototype Object
B.2.4.1 RegExp.prototype.compile ( pattern ,
flags )
This method performs the following steps when called:
Let O be the this value.
Perform ? RequireInternalSlot (O ,
[[RegExpMatcher]] ).
If pattern is an Object and pattern
has a [[RegExpMatcher]] internal slot, then
If flags is not undefined , throw a
TypeError exception.
Let P be pattern .[[OriginalSource]] .
Let F be pattern .[[OriginalFlags]] .
Else,
Let P be pattern .
Let F be flags .
Return ? RegExpInitialize (O ,
P , F ).
Note
This method completely reinitializes the this value RegExp with a
new pattern and flags. An implementation may interpret use of this method as an
assertion that the resulting RegExp object will be used multiple times and hence is
a candidate for extra optimization.
B.3 Other Additional Features
B.3.1 Labelled Function Declarations
Prior to ECMAScript 2015, the specification of LabelledStatement did not allow for the
association of a statement label with a FunctionDeclaration . However, a labelled
FunctionDeclaration was
an allowable extension for non-strict code and most browser-hosted
ECMAScript implementations supported that extension. In ECMAScript 2015 and later, the grammar
production for LabelledStatement permits use of FunctionDeclaration as a
LabelledItem but 14.13.1
includes an Early Error rule that produces a Syntax Error if that occurs. That rule is modified
with the addition of the highlighted text:
LabelledItem : FunctionDeclaration
It is a Syntax Error if any source text that is strict mode
code is matched by this production.
Note
B.3.2 Block-Level Function Declarations Web Legacy Compatibility
Semantics
Prior to ECMAScript 2015, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an
element of a Block statement's
StatementList . However,
support for that form of FunctionDeclaration was an allowable
extension and most browser-hosted ECMAScript implementations permitted them. Unfortunately, the
semantics of such declarations differ among those implementations. Because of these semantic
differences, existing web ECMAScript source text that uses Block level function declarations is only
portable among browser implementations if the usage only depends upon the semantic intersection
of all of the browser implementations for such declarations. The following are the use cases
that fall within that intersection semantics:
A function is declared and only referenced within a single block.
One or more FunctionDeclaration s whose
BindingIdentifier is the name
f occur within the function code of an enclosing function g
and that declaration is nested within a Block .
No other declaration of f that is not a var declaration
occurs within the function code of g .
All occurrences of f as an IdentifierReference are within
the StatementList
of the Block containing
the declaration of f .
A function is declared and possibly used within a single Block but also referenced by an inner function
definition that is not contained within that same Block .
One or more FunctionDeclaration s whose
BindingIdentifier is the name
f occur within the function code of an enclosing function g
and that declaration is nested within a Block .
No other declaration of f that is not a var declaration
occurs within the function code of g .
There may be occurrences of f as an IdentifierReference within the
StatementList of
the Block containing the
declaration of f .
There is at least one occurrence of f as an IdentifierReference within
another function h that is nested within g and no other
declaration of f shadows the references to f from within
h .
All invocations of h occur after the declaration of f has been
evaluated.
A function is declared and possibly used within a single block but also referenced within
subsequent blocks.
One or more FunctionDeclaration whose
BindingIdentifier is the name
f occur within the function code of an enclosing function g
and that declaration is nested within a Block .
No other declaration of f that is not a var declaration
occurs within the function code of g .
There may be occurrences of f as an IdentifierReference within the
StatementList of
the Block containing the
declaration of f .
There is at least one occurrence of f as an IdentifierReference within the
function code of g that lexically follows the Block containing the declaration of
f .
The first use case is interoperable with the semantics of Block level function declarations provided by ECMAScript
2015. Any pre-existing ECMAScript source text that employs that use case
will operate using the Block level function declarations semantics defined by clauses 10 , 14 , and
15 .
ECMAScript 2015 interoperability for the second and third use cases requires the following
extensions to the clause 10 ,
clause 15 , clause
19.2.1 and
clause 16.1.7 semantics.
If an ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a
warning should be produced when code contains a FunctionDeclaration for which these
compatibility semantics are applied and introduce observable differences from non-compatibility
semantics. For example, if a var binding is not introduced because its introduction would create
an early
error , a warning message should not be produced.
B.3.2.1 Changes to FunctionDeclarationInstantiation
During FunctionDeclarationInstantiation
the following steps are performed in place of step 29 :
If strict is false , then
For each FunctionDeclaration
f that is directly contained in the StatementList of any Block , CaseClause , or
DefaultClause x
such that code Contains
x is true , do
Let F be the StringValue
of the BindingIdentifier
of f .
If replacing the FunctionDeclaration
f with a VariableStatement
that has F as a BindingIdentifier
would not produce any Early Errors for func and
parameterNames does not contain F , then
NOTE: A var binding for F is only instantiated
here if it is neither a VarDeclaredName, the name of a
formal parameter, or another FunctionDeclaration .
If instantiatedVarNames does not contain
F and F is not
"arguments" , then
Perform
! varEnv .CreateMutableBinding(F ,
false ).
Perform
! varEnv .InitializeBinding(F ,
undefined ).
Append F to
instantiatedVarNames .
When the FunctionDeclaration
f is evaluated, perform the following steps in
place of the FunctionDeclaration
Evaluation
algorithm provided in 15.2.6 :
Let fEnv be the running
execution context 's
VariableEnvironment.
Let bEnv be the running
execution context 's
LexicalEnvironment.
Let fObj be
! bEnv .GetBindingValue(F ,
false ).
Perform
! fEnv .SetMutableBinding(F ,
fObj , false ).
Return unused .
B.3.2.2 Changes to GlobalDeclarationInstantiation
During GlobalDeclarationInstantiation
the following steps are performed in place of step 12 :
Perform the following steps:
Let strict be ScriptIsStrict of
script .
If strict is false , then
Let declaredFunctionOrVarNames be the list-concatenation
of declaredFunctionNames and declaredVarNames .
For each FunctionDeclaration
f that is directly contained in the StatementList of any
Block ,
CaseClause , or DefaultClause
x such that script Contains
x is true , do
Let F be the StringValue
of the BindingIdentifier
of f .
If replacing the FunctionDeclaration
f with a VariableStatement
that has F as a BindingIdentifier
would not produce any Early Errors for script ,
then
If HasLexicalDeclaration (env ,
F ) is false , then
Let fnDefinable be
? CanDeclareGlobalVar (env ,
F ).
If fnDefinable is
true , then
NOTE: A var binding for F
is only instantiated here if it is
neither a VarDeclaredName nor the
name of another FunctionDeclaration .
If
declaredFunctionOrVarNames
does not contain F , then
Perform ? CreateGlobalVarBinding (env ,
F ,
false ).
Append F to
declaredFunctionOrVarNames .
When the FunctionDeclaration
f is evaluated, perform
the following steps in place of the
FunctionDeclaration
Evaluation
algorithm provided in 15.2.6 :
Let gEnv be the
running
execution
context 's
VariableEnvironment.
Let bEnv be the
running
execution
context 's
LexicalEnvironment.
Let fObj be
! bEnv .GetBindingValue(F ,
false ).
Perform ? gEnv .SetMutableBinding (F ,
fObj ,
false ).
Return
unused .
B.3.2.3 Changes to EvalDeclarationInstantiation
During EvalDeclarationInstantiation
the following steps are performed in place of step 13 :
If strict is false , then
Let declaredFunctionOrVarNames be the list-concatenation of
declaredFunctionNames and declaredVarNames .
For each FunctionDeclaration
f that is directly contained in the StatementList of any Block , CaseClause , or
DefaultClause x
such that body Contains
x is true , do
Let F be the StringValue
of the BindingIdentifier
of f .
If replacing the FunctionDeclaration
f with a VariableStatement
that has F as a BindingIdentifier
would not produce any Early Errors for body , then
Let bindingExists be false .
Let thisEnv be lexEnv .
Assert : The following
loop will terminate.
Repeat, while thisEnv is not varEnv ,
If thisEnv is not an
Object Environment
Record , then
If
! thisEnv .HasBinding(F )
is true , then
Let bindingExists be
true .
Set thisEnv to thisEnv .[[OuterEnv]] .
If bindingExists is false and
varEnv is a Global
Environment Record , then
If HasLexicalDeclaration (varEnv ,
F ) is false , then
Let fnDefinable be
? CanDeclareGlobalVar (varEnv ,
F ).
Else,
Let fnDefinable be
false .
Else,
Let fnDefinable be
true .
If bindingExists is false and
fnDefinable is true , then
If declaredFunctionOrVarNames does not
contain F , then
If varEnv is a Global
Environment Record ,
then
Perform ? CreateGlobalVarBinding (varEnv ,
F ,
true ).
Else,
Let bindingExists be
! varEnv .HasBinding(F ).
If bindingExists is
false , then
Perform
! varEnv .CreateMutableBinding(F ,
true ).
Perform
! varEnv .InitializeBinding(F ,
undefined ).
Append F to
declaredFunctionOrVarNames .
When the FunctionDeclaration
f is evaluated, perform the following
steps in place of the FunctionDeclaration
Evaluation
algorithm provided in 15.2.6 :
Let gEnv be the running
execution context 's
VariableEnvironment.
Let bEnv be the running
execution context 's
LexicalEnvironment.
Let fObj be
! bEnv .GetBindingValue(F ,
false ).
Perform ? gEnv .SetMutableBinding (F ,
fObj , false ).
Return unused .
B.3.2.4 Changes to Block Static Semantics: Early Errors
The rules for the following production in 14.2.1 are modified
with the addition of the highlighted text:
Block :
{
StatementList
}
B.3.2.5 Changes to switch Statement Static
Semantics: Early Errors
The rules for the following production in 14.12.1
are modified with the addition of the highlighted text:
SwitchStatement
:
switch
(
Expression
)
CaseBlock
B.3.2.6 Changes to BlockDeclarationInstantiation
During BlockDeclarationInstantiation
the following steps are performed in place of step 3.a.ii.1 :
If ! env .HasBinding(dn ) is false , then
Perform ! env .CreateMutableBinding(dn ,
false ).
During BlockDeclarationInstantiation
the following steps are performed in place of step 3.b.iii :
Perform the following steps:
If the binding for fn in env is an uninitialized
binding, then
Perform ! env .InitializeBinding(fn ,
fo ).
Else,
Assert : d is a
FunctionDeclaration .
Perform ! env .SetMutableBinding(fn ,
fo , false ).
B.3.3 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 14.6 :
IfStatement [Yield, Await,
Return] :
if
(
Expression [+In, ?Yield,
?Await]
)
FunctionDeclaration [?Yield,
?Await, ~Default]
else
Statement [?Yield, ?Await,
?Return]
if
(
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
else
FunctionDeclaration [?Yield,
?Await, ~Default]
if
(
Expression [+In, ?Yield,
?Await]
)
FunctionDeclaration [?Yield,
?Await, ~Default]
else
FunctionDeclaration [?Yield,
?Await, ~Default]
if
(
Expression [+In, ?Yield,
?Await]
)
FunctionDeclaration [?Yield,
?Await, ~Default]
[lookahead ≠ else ]
This production only applies when parsing non-strict code . Source text matched
by this production is processed as if each matching occurrence of FunctionDeclaration [?Yield,
?Await, ~Default] was the sole StatementListItem of a
BlockStatement occupying
that position in the source text. The semantics of such a synthetic BlockStatement includes the web legacy
compatibility semantics specified in B.3.2 .
B.3.4 VariableStatements in Catch Blocks
The content of subclause 14.15.1 is
replaced with the following:
Catch :
catch
(
CatchParameter
)
Block
Note
The Block of a Catch clause may contain
var declarations that bind a name that is also bound by the CatchParameter . At
runtime, such bindings are instantiated in the VariableDeclarationEnvironment. They do
not shadow the same-named bindings introduced by the CatchParameter and hence the Initializer for such
var declarations will assign to the corresponding catch parameter rather
than the var binding.
This modified behaviour also applies to var and function declarations
introduced by direct
eval calls contained within the Block of a Catch clause. This change is accomplished by modifying
the algorithm of 19.2.1.3 as follows:
Step 3.d.i.2.a.i
is replaced by:
If thisEnv is not the Environment Record
for a Catch clause, throw a
SyntaxError exception.
Step 13.b.ii.4.a.i.i
is replaced by:
If thisEnv is not the Environment Record
for a Catch clause, let
bindingExists be true .
B.3.5 Initializers in ForIn Statement Heads
The following augments the ForInOfStatement production in
14.7.5 :
ForInOfStatement [Yield,
Await, Return] :
for
(
var
BindingIdentifier [?Yield,
?Await]
Initializer [~In, ?Yield,
?Await]
in
Expression [+In, ?Yield,
?Await]
)
Statement [?Yield, ?Await,
?Return]
This production only applies when parsing non-strict code .
The static semantics of ContainsDuplicateLabels
in 8.3.1 are augmented
with the following:
ForInOfStatement
:
for
(
var
BindingIdentifier
Initializer
in
Expression
)
Statement
Return ContainsDuplicateLabels
of Statement with
argument labelSet .
The static semantics of ContainsUndefinedBreakTarget
in 8.3.2 are
augmented with the following:
ForInOfStatement
:
for
(
var
BindingIdentifier
Initializer
in
Expression
)
Statement
Return ContainsUndefinedBreakTarget
of Statement with
argument labelSet .
The static semantics of ContainsUndefinedContinueTarget
in 8.3.3 are
augmented with the following:
ForInOfStatement
:
for
(
var
BindingIdentifier
Initializer
in
Expression
)
Statement
Return ContainsUndefinedContinueTarget
of Statement with
arguments iterationSet and « ».
The static semantics of IsDestructuring in 14.7.5.2 are augmented with
the following:
BindingIdentifier
:
Identifier
yield
await
Return false .
The static semantics of VarDeclaredNames in
8.2.6 are augmented with
the following:
ForInOfStatement
:
for
(
var
BindingIdentifier
Initializer
in
Expression
)
Statement
Let names1 be the BoundNames of BindingIdentifier .
Let names2 be the VarDeclaredNames of
Statement .
Return the list-concatenation of
names1 and names2 .
The static semantics of VarScopedDeclarations
in 8.2.7 are augmented
with the following:
ForInOfStatement
:
for
(
var
BindingIdentifier
Initializer
in
Expression
)
Statement
Let declarations1 be « BindingIdentifier ».
Let declarations2 be the VarScopedDeclarations
of Statement .
Return the list-concatenation of
declarations1 and declarations2 .
The runtime semantics of ForInOfLoopEvaluation
in 14.7.5.5 are
augmented with the following:
ForInOfStatement
:
for
(
var
BindingIdentifier
Initializer
in
Expression
)
Statement
Let bindingId be the StringValue of BindingIdentifier .
Let lhs be ? ResolveBinding (bindingId ).
If IsAnonymousFunctionDefinition (Initializer ) is
true , then
Let value be ? NamedEvaluation of Initializer with
argument bindingId .
Else,
Let rhs be ? Evaluation of
Initializer .
Let value be ? GetValue (rhs ).
Perform ? PutValue (lhs , value ).
Let keyResult be ? ForIn/OfHeadEvaluation (« », Expression ,
enumerate ).
Return ? ForIn/OfBodyEvaluation (BindingIdentifier ,
Statement ,
keyResult , enumerate ,
var-binding , labelSet ).
B.3.6 The [[IsHTMLDDA]] Internal Slot
An [[IsHTMLDDA]] internal slot may exist on
host-defined objects. Objects with an [[IsHTMLDDA]] internal slot behave like undefined in
the ToBoolean and IsLooselyEqual abstract operations
and when used as an operand for the typeof operator .
Note
Objects with an [[IsHTMLDDA]] internal slot are never created by
this specification. However, the document.all
object in web browsers is a host-defined exotic object with this slot
that exists for web compatibility purposes. There are no other known examples of this
type of object and implementations should not create any with the exception of
document.all.
B.3.6.1 Changes to ToBoolean
The following step replaces step 3 of
ToBoolean :
If argument is an Object and argument
has an [[IsHTMLDDA]] internal slot, return
false .
B.3.6.2 Changes to IsLooselyEqual
The following steps replace step 4
of IsLooselyEqual :
Perform the following steps:
If x is an Object , x
has an [[IsHTMLDDA]] internal slot, and
y is either undefined or
null , return true .
If x is either undefined or
null , y is an Object ,
and y has an [[IsHTMLDDA]] internal
slot, return true .
B.3.6.3 Changes to the typeof Operator
The following step replaces step 12 of
the evaluation semantics
for typeof :
If val has an [[IsHTMLDDA]] internal slot,
return "undefined" .
B.3.7 Non-default behaviour in HostMakeJobCallback
The HostMakeJobCallback abstract operation
allows hosts which are web
browsers to specify non-default behaviour.
B.3.8 Non-default behaviour in HostEnsureCanAddPrivateElement
The HostEnsureCanAddPrivateElement
abstract operation allows hosts which are web browsers to specify non-default
behaviour.
Annex C (informative) The Strict Mode of
ECMAScript
The strict mode restriction and exceptions
implements, interface, let, package,
private, protected, public, static, and
yield are reserved words within strict mode
code . (12.7.2 ).
A conforming implementation, when processing strict mode code , must disallow
instances of the productions
NumericLiteral ::
LegacyOctalIntegerLiteral
and
DecimalIntegerLiteral
:: NonOctalDecimalIntegerLiteral
.
A conforming implementation, when processing strict mode code , must disallow
instances of the productions
EscapeSequence ::
LegacyOctalEscapeSequence
and
EscapeSequence ::
NonOctalDecimalEscapeSequence
.
Assignment to an undeclared identifier or otherwise unresolvable reference does not create a
property in the global object . When a simple assignment occurs
within strict
mode code , its LeftHandSideExpression must not evaluate to
an unresolvable Reference. If it does a ReferenceError exception is thrown
(6.2.5.6 ). The
LeftHandSideExpression
also may not be a reference to a data property with the attribute value { [[Writable]] : false }, to an accessor
property with the attribute value { [[Set]] :
undefined }, nor to a non-existent property of an object whose [[Extensible]] internal slot is false . In these cases a
TypeError exception is thrown (13.15 ).
An IdentifierReference with
the StringValue
"eval" or "arguments" may not appear as the LeftHandSideExpression of an
Assignment operator (13.15 ) or of an UpdateExpression (13.4 ) or as the UnaryExpression operated upon by a Prefix
Increment (13.4.4 ) or a Prefix Decrement
(13.4.5 ) operator.
Arguments objects for strict functions define a non-configurable accessor
property "callee" which throws a
TypeError exception on access (10.4.4.6 ).
Arguments objects for strict functions do not dynamically share their
array-indexed
property values with the corresponding formal parameter bindings of their functions. (10.4.4 ).
For strict
functions , if an arguments object is created the binding of the local
identifier arguments to the arguments object is immutable and hence may not be the
target of an assignment expression. (10.2.11 ).
It is a SyntaxError if the StringValue of a BindingIdentifier is either
"eval" or "arguments" within strict mode
code (13.1.1 ).
Strict mode eval code cannot instantiate variables or functions in the variable environment of the
caller to eval. Instead, a new variable environment is created and that environment is used for
declaration binding instantiation for the eval code (19.2.1 ).
If this is evaluated within strict mode code , then the
this value is not coerced to an object. A this value of either
undefined or null is not converted to the global
object and primitive values are not converted to wrapper objects. The
this value passed via a function call (including calls made using
Function.prototype.apply and Function.prototype.call) do not coerce the
passed this value to an object (10.2.1.2 , 20.2.3.1 , 20.2.3.3 ).
When a delete operator occurs within strict mode code , a
SyntaxError is thrown if its UnaryExpression is a direct reference to a
variable, function argument, or function name (13.5.1.1 ).
When a delete operator occurs within strict mode code , a
TypeError is thrown if the property to be deleted has the attribute { [[Configurable]] : false } or otherwise cannot be deleted
(13.5.1.2 ).
Strict mode
code may not include a WithStatement . The occurrence of a WithStatement in such a context is a
SyntaxError (14.11.1 ).
It is a SyntaxError if a CatchParameter occurs within strict mode
code and the BoundNames of CatchParameter contains either
eval or arguments (14.15.1 ).
It is a SyntaxError if the same BindingIdentifier appears more than once in the
FormalParameters of a
strict
function . An attempt to create such a function using a Function, Generator,
or AsyncFunction constructor is a SyntaxError
(15.2.1 ,
20.2.1.1.1 ).
An implementation may not extend, beyond that defined in this specification, the meanings within
strict
functions of properties named "caller" or
"arguments" of function instances.
Annex D (informative) Host Layering Points
See 4.2 for the definition of host .
D.1 Host Hooks
HostCallJobCallback (...)
HostEnqueueFinalizationRegistryCleanupJob (...)
HostEnqueueGenericJob (...)
HostEnqueuePromiseJob (...)
HostEnqueueTimeoutJob (...)
HostEnsureCanCompileStrings (...)
HostFinalizeImportMeta (...)
HostGetImportMetaProperties (...)
HostGrowSharedArrayBuffer (...)
HostHasSourceTextAvailable (...)
HostLoadImportedModule (...)
HostGetSupportedImportAttributes (...)
HostMakeJobCallback (...)
HostPromiseRejectionTracker (...)
HostResizeArrayBuffer (...)
InitializeHostDefinedRealm (...)
D.2 Host-defined Fields
[[HostDefined]] on Realm Records : See Table
24 .
[[HostDefined]] on Script Records : See Table
39 .
[[HostDefined]] on Module Records : See
Table 43 .
[[HostDefined]] on JobCallback Records : See
Table
28 .
[[HostSynchronizesWith]] on Candidate Executions: See Table 101 .
[[IsHTMLDDA]] : See B.3.6 .
D.3 Host-defined Objects
The global
object : See clause 19 .
D.4 Running Jobs
Preparation steps before, and cleanup steps after, invocation of Job Abstract Closures . See 9.5 .
D.5 Internal Methods of Exotic Objects
Any of the essential internal methods in Table 4 for any
exotic
object not specified within this specification.
D.6 Built-in Objects and Methods
Any built-in objects and methods not defined within this specification, except as restricted in
17.1 .
Annex E (informative) Corrections and
Clarifications in ECMAScript 2015 with Possible Compatibility Impact
9.1.1.4.14 -9.1.1.4.17 Edition 5 and 5.1 used a
property existence test to determine whether a global object property corresponding to a new global
declaration already existed. ECMAScript 2015 uses an own property existence test. This corresponds to
what has been most commonly implemented by web browsers.
10.4.2.1 : The
5th Edition moved the capture of the current array length prior to the integer conversion of the
array index or new
length value. However, the captured length value could become invalid if the conversion process has the
side-effect of changing the array length. ECMAScript 2015 specifies that the current array length must
be captured after the possible occurrence of such side-effects.
21.4.1.31 : Previous
editions permitted the TimeClip abstract operation to return either
+0 𝔽 or -0 𝔽 as the representation of a 0
time value . ECMAScript 2015 specifies that
+0 𝔽 always returned. This means that for ECMAScript 2015 the time value of a Date is never observably
-0 𝔽 and methods that return time values never return
-0 𝔽 .
21.4.1.32 : If a UTC offset representation is
not present, the local time zone is used. Edition 5.1 incorrectly stated that a missing time zone should
be interpreted as "z" .
21.4.4.36 : If the year cannot be
represented using the Date Time String Format specified in 21.4.1.32 a RangeError exception
is thrown. Previous editions did not specify the behaviour for that case.
21.4.4.41 : Previous editions did not specify
the value returned by Date.prototype.toString when the time value is NaN .
ECMAScript 2015 specifies the result to be the String value "Invalid Date" .
22.2.4.1 , 22.2.6.13.1 : Any LineTerminator code points in
the value of the "source" property of a RegExp instance must be expressed using an
escape sequence. Edition 5.1 only required the escaping of /.
22.2.6.8 , 22.2.6.11 : In previous editions,
the specifications for String.prototype.match and String.prototype.replace was
incorrect for cases where the pattern argument was a RegExp value whose global flag is set.
The previous specifications stated that for each attempt to match the pattern, if lastIndex
did not change, it should be incremented by 1. The correct behaviour is that lastIndex
should be incremented by 1 only if the pattern matched the empty String.
23.1.3.30 : Previous editions did not specify how
a NaN value returned by a comparator was interpreted by
Array.prototype.sort. ECMAScript 2015 specifies that such as value is treated as if
+0 𝔽 was returned from the comparator . ECMAScript 2015 also
specifies that ToNumber
is applied to the result returned by a comparator . In previous editions, the effect of a
comparator result that is not a Number
value was implementation-defined . In practice,
implementations call ToNumber .
Annex F (informative) Additions and Changes
That Introduce Incompatibilities with Prior Editions
6.2.5 : In ECMAScript 2015,
Function calls are not allowed to return a Reference Record .
7.1.4.1 : In ECMAScript 2015,
ToNumber applied to a
String value now recognizes and converts BinaryIntegerLiteral and OctalIntegerLiteral numeric
strings. In previous editions such strings were converted to NaN .
9.3 : In
ECMAScript 2018, Template objects are canonicalized based on Parse Node (source location),
instead of across all occurrences of that template literal or tagged template in a Realm in previous editions.
12.2 : In
ECMAScript 2016, Unicode 8.0.0 or higher is mandated, as opposed to ECMAScript 2015 which mandated
Unicode 5.1. In particular, this caused U+180E MONGOLIAN VOWEL SEPARATOR, which was in the
Space_Separator (Zs) category and thus treated as whitespace in ECMAScript
2015, to be moved to the Format (Cf) category (as of Unicode 6.3.0). This
causes whitespace-sensitive methods to behave differently. For example,
"\u180E".trim().length was 0 in previous editions, but 1 in
ECMAScript 2016 and later. Additionally, ECMAScript 2017 mandated always using the latest version of the
Unicode Standard.
12.7 : In ECMAScript 2015, the valid code points
for an IdentifierName are specified
in terms of the Unicode properties “ID_Start” and “ID_Continue”. In previous editions, the valid IdentifierName or Identifier code points were specified by
enumerating various Unicode code point categories.
12.10.1 : In ECMAScript 2015,
Automatic Semicolon Insertion adds a semicolon at the end of a do-while statement if the semicolon is
missing. This change aligns the specification with the actual behaviour of most existing
implementations.
13.2.5.1 : In
ECMAScript 2015, it is no longer an early error to have duplicate property names in Object
Initializers.
13.15.1 : In
ECMAScript 2015, strict mode code containing an assignment to an
immutable binding such as the function name of a FunctionExpression does not produce an early error . Instead it
produces a runtime error.
14.2 : In ECMAScript 2015, a
StatementList beginning with the
token let followed by the input elements LineTerminator then Identifier is the start of a LexicalDeclaration . In previous editions, automatic
semicolon insertion would always insert a semicolon before the Identifier input element.
14.5 : In ECMAScript 2015, a StatementListItem beginning with the
token let followed by the token [ is the start of a LexicalDeclaration . In previous editions such a
sequence would be the start of an ExpressionStatement .
14.6.2 : In ECMAScript 2015,
the normal result of an IfStatement is
never the value empty . If no Statement part is evaluated or if the evaluated Statement part produces a normal completion containing
empty , the result of the IfStatement is undefined .
14.7 : In ECMAScript 2015, if the (
token of a for statement is immediately followed by the token sequence let [ then the
let is treated as the start of a LexicalDeclaration . In previous editions such a
token sequence would be the start of an Expression .
14.7 : In ECMAScript 2015, if the ( token of a
for-in statement is immediately followed by the token sequence let [ then the
let is treated as the start of a ForDeclaration . In previous editions such a token
sequence would be the start of an LeftHandSideExpression .
14.7 : Prior to ECMAScript 2015, an
initialization expression could appear as part of the VariableDeclaration that precedes the
in keyword . In ECMAScript 2015, the ForBinding in that same position does not
allow the occurrence of such an initializer. In ECMAScript 2017, such an initializer is permitted only
in non-strict
code .
14.7 : In ECMAScript 2015, the result of
evaluating an IterationStatement
is never a normal completion whose [[Value]] is empty . If the Statement part of an IterationStatement is not evaluated or if the final
evaluation of the Statement part produces
a normal completion whose [[Value]] is empty , the result of evaluating the IterationStatement is a normal completion whose [[Value]] is undefined .
14.11.2 : In ECMAScript
2015, the result of evaluating a WithStatement is never a normal completion whose [[Value]] is empty . If evaluation of the Statement part of a WithStatement produces a normal completion whose [[Value]] is empty , the result of evaluating the WithStatement is a normal completion whose [[Value]] is undefined .
14.12.4 : In ECMAScript
2015, the result of evaluating a SwitchStatement is never a normal completion whose [[Value]] is empty . If evaluation of the CaseBlock part of a SwitchStatement produces a normal completion whose [[Value]] is empty , the result of evaluating the SwitchStatement is a normal completion whose [[Value]] is undefined .
14.15 : In
ECMAScript 2015, it is an early
error for a Catch
clause to contain a var declaration for the same Identifier that appears as the Catch clause parameter. In previous editions, such a variable
declaration would be instantiated in the enclosing variable environment but the declaration's Initializer value would be assigned to the
Catch parameter.
14.15 ,
19.2.1.3 : In ECMAScript 2015, a runtime
SyntaxError is thrown if a Catch clause evaluates a non-strict direct eval
whose eval code includes a var or FunctionDeclaration declaration that binds
the same Identifier that appears as the
Catch clause parameter.
14.15.3 : In ECMAScript
2015, the result of a TryStatement is
never the value empty . If the Block part of a TryStatement evaluates to a normal completion containing
empty , the result of the TryStatement is undefined . If the
Block part of a TryStatement evaluates to a throw completion and it has a
Catch part that evaluates to a normal completion containing
empty , the result of the TryStatement is undefined if there is
no Finally clause or if its Finally clause evaluates to an
empty normal
completion .
15.4.5 In ECMAScript
2015, the function
objects that are created as the values of the [[Get]] or
[[Set]] attribute of accessor properties in an ObjectLiteral are not constructor functions and they do not have a
"prototype" own property. In the previous edition, they were constructors and had a
"prototype" property.
20.1.2.6 :
In ECMAScript 2015, if the argument to Object.freeze is not an object it is treated as if
it was a non-extensible ordinary object with no own properties. In the previous
edition, a non-object argument always causes a TypeError to be thrown.
20.1.2.8 : In ECMAScript 2015, if the
argument to Object.getOwnPropertyDescriptor is not an object an attempt is made to coerce
the argument using ToObject . If the coercion is successful the result is used
in place of the original argument value. In the previous edition, a non-object argument always causes a
TypeError to be thrown.
20.1.2.10 : In ECMAScript 2015, if the
argument to Object.getOwnPropertyNames is not an object an attempt is made to coerce the
argument using ToObject . If the coercion is successful the result is used
in place of the original argument value. In the previous edition, a non-object argument always causes a
TypeError to be thrown.
20.1.2.12 : In ECMAScript 2015, if the argument
to Object.getPrototypeOf is not an object an attempt is made to coerce the argument using
ToObject . If the
coercion is successful the result is used in place of the original argument value. In the previous
edition, a non-object argument always causes a TypeError to be thrown.
20.1.2.16 : In ECMAScript 2015, if the argument to
Object.isExtensible is not an object it is treated as if it was a non-extensible ordinary object
with no own properties. In the previous edition, a non-object argument always causes a
TypeError to be thrown.
20.1.2.17 : In ECMAScript 2015, if the argument to
Object.isFrozen is not an object it is treated as if it was a non-extensible ordinary object
with no own properties. In the previous edition, a non-object argument always causes a
TypeError to be thrown.
20.1.2.18 : In ECMAScript 2015, if the argument to
Object.isSealed is not an object it is treated as if it was a non-extensible ordinary object
with no own properties. In the previous edition, a non-object argument always causes a
TypeError to be thrown.
20.1.2.19 : In
ECMAScript 2015, if the argument to Object.keys is not an object an attempt is made to
coerce the argument using ToObject . If the coercion is successful the result is used
in place of the original argument value. In the previous edition, a non-object argument always causes a
TypeError to be thrown.
20.1.2.20 : In ECMAScript 2015, if the
argument to Object.preventExtensions is not an object it is treated as if it was a
non-extensible ordinary
object with no own properties. In the previous edition, a non-object argument
always causes a TypeError to be thrown.
20.1.2.22 : In
ECMAScript 2015, if the argument to Object.seal is not an object it is treated as if it was
a non-extensible ordinary
object with no own properties. In the previous edition, a non-object argument
always causes a TypeError to be thrown.
20.2.3.2 : In ECMAScript 2015, the [[Prototype]] internal slot of a bound function is set to the [[GetPrototypeOf]] value of its target function. In the previous edition, [[Prototype]] was always set to %Function.prototype% .
20.2.4.1 : In ECMAScript 2015, the
"length" property of function instances is configurable. In previous editions it was
non-configurable.
20.5.6.2 : In ECMAScript
2015, the [[Prototype]] internal slot of a NativeError constructor is the Error
constructor . In
previous editions it was the Function prototype
object .
21.4.4 In ECMAScript 2015,
the Date prototype object is not
a Date instance. In previous editions it was a Date instance whose TimeValue was NaN .
22.1.3.12 In ECMAScript 2015, the
String.prototype.localeCompare function must treat Strings that are canonically equivalent
according to the Unicode Standard as being identical. In previous editions implementations were
permitted to ignore canonical equivalence and could instead use a bit-wise comparison.
22.1.3.28 and 22.1.3.30 In ECMAScript 2015,
lowercase/upper conversion processing operates on code points. In previous editions such the conversion
processing was only applied to individual code units. The only affected code points are those in the
Deseret block of Unicode.
22.1.3.32 In ECMAScript 2015, the
String.prototype.trim method is defined to recognize white space code points that may exist
outside of the Unicode BMP. However, as of Unicode 7 no such code points are defined. In previous
editions such code points would not have been recognized as white space.
22.2.4.1 In ECMAScript 2015, If the
pattern argument is a RegExp instance and the flags argument is not
undefined , a new RegExp instance is created just like pattern except that
pattern 's flags are replaced by the argument flags . In previous editions a
TypeError exception was thrown when pattern was a RegExp instance and
flags was not undefined .
22.2.6 In ECMAScript 2015,
the RegExp prototype object is
not a RegExp instance. In previous editions it was a RegExp instance whose pattern is the empty String.
22.2.6 In ECMAScript 2015,
"source" , "global" , "ignoreCase" , and
"multiline" are accessor properties defined on the RegExp prototype object . In
previous editions they were data properties defined on RegExp instances.
25.4.15 :
In ECMAScript 2019, Atomics.wake has been renamed to Atomics.notify to prevent
confusion with Atomics.wait.
27.1.6.4 , 27.6.3.6 : In ECMAScript 2019, the number of
Jobs enqueued by await
was reduced, which could create an observable difference in resolution order between a
then() call and an await expression.
Bibliography
IEEE 754-2019 : IEEE Standard for Floating-Point Arithmetic .
Institute of Electrical and Electronic Engineers, New York (2019)
Note
There are no normative changes between IEEE 754-2008 and IEEE 754-2019 that affect the
ECMA-262 specification.
The Unicode Standard , available at <https://unicode.org/versions/latest >
Unicode Technical Note #5: Canonical Equivalence in Applications , available at <https://unicode.org/notes/tn5/ >
Unicode Technical Standard #10: Unicode Collation Algorithm , available at <https://unicode.org/reports/tr10/ >
Unicode Standard Annex #15, Unicode Normalization Forms , available at <https://unicode.org/reports/tr15/ >
Unicode Standard Annex #18: Unicode Regular Expressions , available at <https://unicode.org/reports/tr18/ >
Unicode Standard Annex #24: Unicode Script Property , available at <https://unicode.org/reports/tr24/ >
Unicode Standard Annex #31, Unicode Identifiers and Pattern Syntax , available at <https://unicode.org/reports/tr31/ >
Unicode Standard Annex #44: Unicode Character Database , available at <https://unicode.org/reports/tr44/ >
Unicode Technical Standard #51: Unicode Emoji , available at <https://unicode.org/reports/tr51/ >
IANA Time Zone Database , available at <https://www.iana.org/time-zones >
ISO 8601:2004(E) Data elements and interchange formats — Information interchange — Representation
of dates and times
RFC 1738 “Uniform Resource Locators (URL)” , available at <https://tools.ietf.org/html/rfc1738 >
RFC 2396 “Uniform Resource Identifiers (URI): Generic Syntax” , available at <https://tools.ietf.org/html/rfc2396 >
RFC 3629 “UTF-8, a transformation format of ISO 10646” , available at <https://tools.ietf.org/html/rfc3629 >
RFC 7231 “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content” , available at <https://tools.ietf.org/html/rfc7231 >
Colophon
This specification is authored on GitHub in a plaintext
source format called Ecmarkup . Ecmarkup is an HTML
and Markdown dialect that provides a framework and toolset for authoring ECMAScript specifications in
plaintext and processing the specification into a full-featured HTML rendering that follows the
editorial conventions for this document. Ecmarkup builds on and integrates a number of other formats and
technologies including Grammarkdown for defining
syntax and Ecmarkdown for authoring algorithm steps.
PDF renderings of this specification are produced using a print stylesheet which takes advantage of the
CSS Paged Media specification and is converted using PrinceXML .
Prior editions of this specification were authored using Word—the Ecmarkup source text that formed the
basis of this edition was produced by converting the ECMAScript 2015 Word document to Ecmarkup using an
automated conversion tool.
Copyright & Software License
Ecma International
Rue du Rhone 114
CH-1204 Geneva
Tel: +41 22 849 6000
Fax: +41 22 849 6001
Web: https://ecma-international.org/
Copyright Notice
© 2025 Ecma International
This draft document may be copied and furnished to others, and derivative works that comment on or
otherwise explain it or assist in its implementation may be prepared, copied, published, and
distributed, in whole or in part, without restriction of any kind, provided that the above copyright
notice and this section are included on all such copies and derivative works. However, this document
itself may not be modified in any way, including by removing the copyright notice or references to
Ecma International, except as needed for the purpose of developing any document or deliverable
produced by Ecma International.
This disclaimer is valid only prior to final version of this document. After approval all rights on
the standard are reserved by Ecma International.
The limited permissions are granted through the standardization phase and will not be revoked by Ecma
International or its successors or assigns during this time.
This document and the information contained herein is provided on an "AS IS" basis and ECMA
INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY
IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Software License
All Software contained in this document ("Software") is protected by copyright and is being made
available under the "BSD License", included below. This Software may be subject to third party rights
(rights from parties other than Ecma International), including patent rights, and no licenses under such
third party rights are granted under this license even if the third party concerned is a member of Ecma
International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm
FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA
INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
Neither the name of the authors nor Ecma International may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.